ということで、何となくSwift
でReactiveCocoa
+Realm
を使ったサンプルを作ってみた。
使用したライブラリ
Library | Version | 備考 |
---|---|---|
ReactiveCocoa | 2.4.4 | - |
Realm | 0.92.2 | RealmSwiftを仕様 |
ReactiveCocoaについて
ReactiveCocoaを使うにあたって、以下を参考にした。
http://blog.scottlogic.com/2014/07/24/mvvm-reactivecocoa-swift.html
サンプルコード
Model
import RealmSwift
class Note: Object {
dynamic var text = ""
}
ViewModel
import UIKit
import RealmSwift
class ViewModel: NSObject {
var token: NotificationToken?
var notes = Realm().objects(Note)
let updateSignal: RACSubject
override init() {
updateSignal = RACSubject()
super.init()
// RealmのNotificationBlockをReactiveCocoaとうまく使うにはどうするのがいいのか
// 取りあえずRACSubjectを使ってSignalを送る用にしたみが...
token = Realm().addNotificationBlock { [unowned self] note, realm in
self.updateSignal.sendNext(nil)
}
}
func numberOfSections() -> Int {
return 1
}
func numberOfItemsInSection(seciont: Int) -> Int {
return Int(notes.count)
}
func deleteAtIndex(index: Int) {
let realm = Realm()
realm.write {
realm.delete(self.notes[index])
}
}
func noteAtIndex(index: Int) -> Note? {
return notes[index]
}
}
TableViewController
import UIKit
import RealmSwift
class ListViewController: UITableViewController {
var selectedUuid: String?
var viewModel: ViewModel?
var tableViewDelegate: AnyObject?
override func viewDidLoad() {
super.viewDidLoad()
self.viewModel = ListViewModel()
viewModel?.updateSignal.subscribeNext({[weak self](value:AnyObject?) -> Void in
self!.tableView.reloadData()
})
// DelegateProxyはこんな感じでいいのだろうか
// withProtocol: の引数はNSProtocolFromStringを使ってなかば無理矢理に
tableViewDelegate = RACDelegateProxy(withProtocol:NSProtocolFromString("UITableViewDelegate"))
tableViewDelegate?.rac_signalForSelector("tableView:didSelectRowAtIndexPath:").subscribeNext({ (RACTuple tuple) -> Void in
println("\(tuple)")
})
tableView.delegate = tableViewDelegate as? UITableViewDelegate
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// MARK: - Table view data source
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return viewModel!.numberOfSections()
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return viewModel!.numberOfItemsInSection(section)
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("BasicCell", forIndexPath: indexPath) as! UITableViewCell
if let note = viewModel!.noteAtIndex(indexPath.row) {
cell.textLabel?.text = note.text
}
return cell
}
// Override to support conditional editing of the table view.
override func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool {
// Return NO if you do not want the specified item to be editable.
return true
}
// Override to support editing the table view.
override func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
if editingStyle == .Delete {
// Delete the row from the data source
viewModel?.deleteAtIndex(indexPath.row)
} else if editingStyle == .Insert {
// Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
}
}
}