mirror of
https://github.com/modo-studio/SugarRecord.git
synced 2024-09-11 14:36:41 +03:00
Add Observable examples
This commit is contained in:
parent
bb8386ee46
commit
4c9ed87fb3
@ -39,6 +39,10 @@ class CoreDataBasicView: UIViewController, UITableViewDelegate, UITableViewDataS
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
deinit {
|
||||
print("🚀🚀🚀 Deallocating \(self) 🚀🚀🚀")
|
||||
}
|
||||
|
||||
|
||||
// MARK: - Lifecycle
|
||||
|
||||
|
@ -34,13 +34,17 @@ class CoreDataObservableView: UIViewController, UITableViewDelegate, UITableView
|
||||
|
||||
init() {
|
||||
super.init(nibName: nil, bundle: nil)
|
||||
self.title = "CoreData Basic"
|
||||
self.title = "CoreData Observable"
|
||||
}
|
||||
|
||||
required init?(coder aDecoder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
deinit {
|
||||
print("🚀🚀🚀 Deallocating \(self) 🚀🚀🚀")
|
||||
}
|
||||
|
||||
|
||||
// MARK: - Lifecycle
|
||||
|
||||
@ -75,21 +79,23 @@ class CoreDataObservableView: UIViewController, UITableViewDelegate, UITableView
|
||||
}
|
||||
|
||||
private func setupObservable() {
|
||||
db.observable(Request<BasicObject>())
|
||||
db.observable(Request<BasicObject>().sortedWith("date", ascending: true))
|
||||
.rx_observe()
|
||||
.subscribeNext { (change) in
|
||||
.subscribeNext { [weak self] (change) in
|
||||
switch change {
|
||||
case .Initial(let entities):
|
||||
self?.entities = entities.map(CoreDataBasicEntity.init)
|
||||
break
|
||||
case .Update(let deletions, let insertions, let modifications):
|
||||
modifications.forEach { [weak self] in self?.entities[$0.0] = CoreDataBasicEntity(object: $0.1) }
|
||||
insertions.forEach { [weak self] in self?.entities.insert(CoreDataBasicEntity(object: $0.1), atIndex: $0.0) }
|
||||
deletions.forEach({ [weak self] in self?.entities.removeAtIndex($0) })
|
||||
break
|
||||
default:
|
||||
break
|
||||
}
|
||||
}
|
||||
.addDisposableTo(self.disposeBag)
|
||||
// self.entities = try! db.fetch(Request<BasicObject>()).map(CoreDataBasicEntity.init)
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -38,6 +38,10 @@ class RealmBasicView: UIViewController, UITableViewDelegate, UITableViewDataSour
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
deinit {
|
||||
print("🚀🚀🚀 Deallocating \(self) 🚀🚀🚀")
|
||||
}
|
||||
|
||||
|
||||
// MARK: - Lifecycle
|
||||
|
||||
@ -120,25 +124,4 @@ class RealmBasicView: UIViewController, UITableViewDelegate, UITableViewDataSour
|
||||
private func updateData() {
|
||||
self.entities = try! db.fetch(Request<RealmBasicObject>()).map(RealmBasicEntity.init)
|
||||
}
|
||||
}
|
||||
|
||||
class RealmBasicObject: Object {
|
||||
dynamic var date: NSDate = NSDate()
|
||||
dynamic var name: String = ""
|
||||
|
||||
internal override class func primaryKey() -> String? {
|
||||
return "name"
|
||||
}
|
||||
}
|
||||
|
||||
class RealmBasicEntity {
|
||||
let dateString: String
|
||||
let name: String
|
||||
init(object: RealmBasicObject) {
|
||||
let dateFormater = NSDateFormatter()
|
||||
dateFormater.timeStyle = NSDateFormatterStyle.ShortStyle
|
||||
dateFormater.dateStyle = NSDateFormatterStyle.ShortStyle
|
||||
self.dateString = dateFormater.stringFromDate(object.date)
|
||||
self.name = object.name
|
||||
}
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
import Foundation
|
||||
|
||||
class RealmBasicEntity {
|
||||
|
||||
// MARK: - Attributes
|
||||
|
||||
let dateString: String
|
||||
let name: String
|
||||
|
||||
|
||||
// MARK: - Init
|
||||
|
||||
init(object: RealmBasicObject) {
|
||||
let dateFormater = NSDateFormatter()
|
||||
dateFormater.timeStyle = NSDateFormatterStyle.ShortStyle
|
||||
dateFormater.dateStyle = NSDateFormatterStyle.ShortStyle
|
||||
self.dateString = dateFormater.stringFromDate(object.date)
|
||||
self.name = object.name
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
import Foundation
|
||||
import RealmSwift
|
||||
|
||||
class RealmBasicObject: Object {
|
||||
|
||||
// MARK: - Attributes
|
||||
|
||||
dynamic var date: NSDate = NSDate()
|
||||
dynamic var name: String = ""
|
||||
|
||||
|
||||
// MARK: - PrimaryKey
|
||||
|
||||
internal override class func primaryKey() -> String? {
|
||||
return "name"
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,141 @@
|
||||
import Foundation
|
||||
import UIKit
|
||||
import SugarRecord
|
||||
import RealmSwift
|
||||
import RxSwift
|
||||
|
||||
class RealmObservableView: UIViewController, UITableViewDelegate, UITableViewDataSource {
|
||||
|
||||
// MARK: - Attributes
|
||||
lazy var db: RealmDefaultStorage = {
|
||||
var configuration = Realm.Configuration()
|
||||
configuration.fileURL = NSURL(fileURLWithPath: databasePath("realm-basic"))
|
||||
let _storage = RealmDefaultStorage(configuration: configuration)
|
||||
return _storage
|
||||
}()
|
||||
lazy var tableView: UITableView = {
|
||||
let _tableView = UITableView(frame: CGRectZero, style: UITableViewStyle.Plain)
|
||||
_tableView.translatesAutoresizingMaskIntoConstraints = false
|
||||
_tableView.delegate = self
|
||||
_tableView.dataSource = self
|
||||
_tableView.registerClass(UITableViewCell.classForCoder(), forCellReuseIdentifier: "default-cell")
|
||||
return _tableView
|
||||
}()
|
||||
var entities: [RealmBasicEntity] = [] {
|
||||
didSet {
|
||||
self.tableView.reloadData()
|
||||
}
|
||||
}
|
||||
var disposeBag: DisposeBag = DisposeBag()
|
||||
|
||||
|
||||
// MARK: - Init
|
||||
|
||||
init() {
|
||||
super.init(nibName: nil, bundle: nil)
|
||||
self.title = "Realm Observable View"
|
||||
}
|
||||
|
||||
required init?(coder aDecoder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
deinit {
|
||||
print("🚀🚀🚀 Deallocating \(self) 🚀🚀🚀")
|
||||
}
|
||||
|
||||
|
||||
// MARK: - Lifecycle
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
setup()
|
||||
}
|
||||
|
||||
|
||||
// MARK: - Private
|
||||
|
||||
private func setup() {
|
||||
setupView()
|
||||
setupNavigationItem()
|
||||
setupTableView()
|
||||
setupObservable()
|
||||
}
|
||||
|
||||
private func setupView() {
|
||||
self.view.backgroundColor = UIColor.whiteColor()
|
||||
}
|
||||
|
||||
private func setupNavigationItem() {
|
||||
self.navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.Add, target: self, action: #selector(RealmBasicView.userDidSelectAdd(_:)))
|
||||
}
|
||||
|
||||
private func setupTableView() {
|
||||
self.view.addSubview(tableView)
|
||||
self.tableView.snp_makeConstraints { (make) -> Void in
|
||||
make.edges.equalTo(self.view)
|
||||
}
|
||||
}
|
||||
|
||||
private func setupObservable() {
|
||||
db.observable(Request<RealmBasicObject>().sortedWith("date", ascending: true))
|
||||
.rx_observe()
|
||||
.subscribeNext { [weak self] (change) in
|
||||
switch change {
|
||||
case .Initial(let entities):
|
||||
self?.entities = entities.map(RealmBasicEntity.init)
|
||||
break
|
||||
case .Update(let deletions, let insertions, let modifications):
|
||||
modifications.forEach { [weak self] in self?.entities[$0.0] = RealmBasicEntity(object: $0.1) }
|
||||
insertions.forEach { [weak self] in self?.entities.insert(RealmBasicEntity(object: $0.1), atIndex: $0.0) }
|
||||
deletions.forEach({ [weak self] in self?.entities.removeAtIndex($0) })
|
||||
break
|
||||
default:
|
||||
break
|
||||
}
|
||||
}
|
||||
.addDisposableTo(self.disposeBag)
|
||||
}
|
||||
|
||||
|
||||
// MARK: - UITableViewDataSource / UITableViewDelegate
|
||||
|
||||
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
|
||||
return self.entities.count
|
||||
}
|
||||
|
||||
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
|
||||
let cell: UITableViewCell = tableView.dequeueReusableCellWithIdentifier("default-cell")!
|
||||
cell.textLabel?.text = "\(entities[indexPath.row].name) - \(entities[indexPath.row].dateString)"
|
||||
return cell
|
||||
}
|
||||
|
||||
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
|
||||
tableView.deselectRowAtIndexPath(indexPath, animated: true)
|
||||
}
|
||||
|
||||
func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
|
||||
if editingStyle == UITableViewCellEditingStyle.Delete {
|
||||
let name = entities[indexPath.row].name
|
||||
try! db.operation({ (context, save) -> Void in
|
||||
guard let obj = try! context.request(RealmBasicObject.self).filteredWith("name", equalTo: name).fetch().first else { return }
|
||||
_ = try? context.remove(obj)
|
||||
save()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// MARK: - Actions
|
||||
|
||||
func userDidSelectAdd(sender: AnyObject!) {
|
||||
try! db.operation { (context, save) -> Void in
|
||||
let _object: RealmBasicObject = try! context.new()
|
||||
_object.date = NSDate()
|
||||
_object.name = randomStringWithLength(10) as String
|
||||
try! context.insert(_object)
|
||||
save()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -56,7 +56,7 @@ class ViewController: UIViewController, UITableViewDataSource, UITableViewDelega
|
||||
// MARK: - UITableViewDataSource / UITableViewDelegate
|
||||
|
||||
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
|
||||
return 3
|
||||
return 4
|
||||
}
|
||||
|
||||
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
|
||||
@ -68,6 +68,8 @@ class ViewController: UIViewController, UITableViewDataSource, UITableViewDelega
|
||||
cell.textLabel?.text = "Realm Basic"
|
||||
case 2:
|
||||
cell.textLabel?.text = "CoreData Observable"
|
||||
case 3:
|
||||
cell.textLabel?.text = "Realm Observable"
|
||||
default:
|
||||
cell.textLabel?.text = ""
|
||||
}
|
||||
@ -84,6 +86,8 @@ class ViewController: UIViewController, UITableViewDataSource, UITableViewDelega
|
||||
self.navigationController?.pushViewController(RealmBasicView(), animated: true)
|
||||
case 2:
|
||||
self.navigationController?.pushViewController(CoreDataObservableView(), animated: true)
|
||||
case 3:
|
||||
self.navigationController?.pushViewController(RealmObservableView(), animated: true)
|
||||
default:
|
||||
break
|
||||
}
|
||||
|
@ -14,6 +14,9 @@
|
||||
2346DAB51CE9F3220047CB5F /* RealmBasicView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2346DAB21CE9F3220047CB5F /* RealmBasicView.swift */; };
|
||||
2346DAB71CE9F3350047CB5F /* BasicObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2346DAB61CE9F3350047CB5F /* BasicObject.swift */; };
|
||||
2346DAB91CE9F34E0047CB5F /* CoreDataBasicEntity.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2346DAB81CE9F34E0047CB5F /* CoreDataBasicEntity.swift */; };
|
||||
235ABB8F1CEA011200C2AEB9 /* RealmObservableView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 235ABB8E1CEA011200C2AEB9 /* RealmObservableView.swift */; };
|
||||
235ABB921CEA012C00C2AEB9 /* RealmBasicObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = 235ABB911CEA012C00C2AEB9 /* RealmBasicObject.swift */; };
|
||||
235ABB941CEA013C00C2AEB9 /* RealmBasicEntity.swift in Sources */ = {isa = PBXBuildFile; fileRef = 235ABB931CEA013C00C2AEB9 /* RealmBasicEntity.swift */; };
|
||||
236B5A171C3886CA00C9E469 /* Basic.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = 236B5A151C3886CA00C9E469 /* Basic.xcdatamodeld */; };
|
||||
23D5927E1C28494500441B41 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 23D592741C28494500441B41 /* Assets.xcassets */; };
|
||||
23D5927F1C28494500441B41 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 23D592761C28494500441B41 /* LaunchScreen.storyboard */; };
|
||||
@ -29,6 +32,9 @@
|
||||
2346DAB21CE9F3220047CB5F /* RealmBasicView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RealmBasicView.swift; sourceTree = "<group>"; };
|
||||
2346DAB61CE9F3350047CB5F /* BasicObject.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BasicObject.swift; sourceTree = "<group>"; };
|
||||
2346DAB81CE9F34E0047CB5F /* CoreDataBasicEntity.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CoreDataBasicEntity.swift; sourceTree = "<group>"; };
|
||||
235ABB8E1CEA011200C2AEB9 /* RealmObservableView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RealmObservableView.swift; sourceTree = "<group>"; };
|
||||
235ABB911CEA012C00C2AEB9 /* RealmBasicObject.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RealmBasicObject.swift; sourceTree = "<group>"; };
|
||||
235ABB931CEA013C00C2AEB9 /* RealmBasicEntity.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RealmBasicEntity.swift; sourceTree = "<group>"; };
|
||||
236B5A161C3886CA00C9E469 /* Basic.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = Basic.xcdatamodel; sourceTree = "<group>"; };
|
||||
23D5925D1C2834DC00441B41 /* SugarRecordExamples.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SugarRecordExamples.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
23D592741C28494500441B41 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
|
||||
@ -101,6 +107,8 @@
|
||||
2346DAB01CE9F3220047CB5F /* Realm */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
235ABB901CEA011B00C2AEB9 /* Models */,
|
||||
235ABB8D1CEA010B00C2AEB9 /* Observable */,
|
||||
2346DAB11CE9F3220047CB5F /* Basic */,
|
||||
);
|
||||
path = Realm;
|
||||
@ -114,6 +122,23 @@
|
||||
path = Basic;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
235ABB8D1CEA010B00C2AEB9 /* Observable */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
235ABB8E1CEA011200C2AEB9 /* RealmObservableView.swift */,
|
||||
);
|
||||
path = Observable;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
235ABB901CEA011B00C2AEB9 /* Models */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
235ABB911CEA012C00C2AEB9 /* RealmBasicObject.swift */,
|
||||
235ABB931CEA013C00C2AEB9 /* RealmBasicEntity.swift */,
|
||||
);
|
||||
path = Models;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
236B5A141C3886BF00C9E469 /* DataModels */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@ -359,9 +384,12 @@
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
2346DAB31CE9F3220047CB5F /* CoreDataBasicView.swift in Sources */,
|
||||
235ABB941CEA013C00C2AEB9 /* RealmBasicEntity.swift in Sources */,
|
||||
2346DAB91CE9F34E0047CB5F /* CoreDataBasicEntity.swift in Sources */,
|
||||
2346DAB71CE9F3350047CB5F /* BasicObject.swift in Sources */,
|
||||
235ABB921CEA012C00C2AEB9 /* RealmBasicObject.swift in Sources */,
|
||||
2346DAB41CE9F3220047CB5F /* CoreDataObservableView.swift in Sources */,
|
||||
235ABB8F1CEA011200C2AEB9 /* RealmObservableView.swift in Sources */,
|
||||
23D592811C28494500441B41 /* ViewController.swift in Sources */,
|
||||
236B5A171C3886CA00C9E469 /* Basic.xcdatamodeld in Sources */,
|
||||
232660A71C28563F00575110 /* Random.swift in Sources */,
|
||||
|
@ -61,7 +61,7 @@ public class CoreDataObservable<T: NSManagedObject where T:Equatable>: Observabl
|
||||
}
|
||||
|
||||
public func controllerDidChangeContent(controller: NSFetchedResultsController) {
|
||||
let deleted = self.batchChanges.filter { $0.isDeletion() }.map { (index: $0.index(), element: $0.object()) }
|
||||
let deleted = self.batchChanges.filter { $0.isDeletion() }.map { $0.index() }
|
||||
let inserted = self.batchChanges.filter { $0.isInsertion() }.map { (index: $0.index(), element: $0.object()) }
|
||||
let updated = self.batchChanges.filter { $0.isUpdate() }.map { (index: $0.index(), element: $0.object()) }
|
||||
self.observer?(ObservableChange.Update(deletions: deleted, insertions: inserted, modifications: updated))
|
||||
|
@ -2,7 +2,7 @@ import Foundation
|
||||
|
||||
public enum ObservableChange<T> {
|
||||
case Initial([T])
|
||||
case Update(deletions: [(index: Int, element: T)], insertions: [(index: Int, element: T)], modifications: [(index: Int, element: T)])
|
||||
case Update(deletions: [Int], insertions: [(index: Int, element: T)], modifications: [(index: Int, element: T)])
|
||||
case Error(NSError)
|
||||
}
|
||||
|
||||
|
@ -47,7 +47,7 @@ public class RealmObservable<T: Object>: Observable<T> {
|
||||
case .Initial(let initial):
|
||||
return ObservableChange.Initial(initial.toArray())
|
||||
case .Update(let objects, let deletions, let insertions, let modifications):
|
||||
let deletions = deletions.map { (index: $0, element: objects[$0]) }
|
||||
let deletions = deletions.map { $0 }
|
||||
let insertions = insertions.map { (index: $0, element: objects[$0]) }
|
||||
let modifications = modifications.map { (index: $0, element: objects[$0]) }
|
||||
return ObservableChange.Update(deletions: deletions, insertions: insertions, modifications: modifications)
|
||||
|
Loading…
Reference in New Issue
Block a user