Skip to content

Instantly share code, notes, and snippets.

@SaganRitual
Last active March 2, 2018 07:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save SaganRitual/6118a26f27378bb7b421e8d7392dff94 to your computer and use it in GitHub Desktop.
Save SaganRitual/6118a26f27378bb7b421e8d7392dff94 to your computer and use it in GitHub Desktop.
Working, bare-bones example of how to use CoreStore's notification mechanism
// Figuring out how CoreStore's monitor/observer mechanism works was a painful
// experience. This is a working example of how to use list object observers and
// single object observers. You'll need CoreStore, of course, to run this.
// Instantiate a Database object and call the .go() method. The reason for the
// Timers is that I wanted to make sure the code would run in asynchronous pieces,
// rather than all on one execution thread, to more-or-less simulate mouse
// clicks in a real app.
//
// https://github.com/JohnEstropia/CoreStore -- don't get me wrong, it was
// worth the pain. But with any luck this example will spare you some headaches.
import Foundation
import CoreStore
class Dog: CoreStoreObject {
let species = Value.Required<String>("species", initial: "")
}
class Database {
var internalCoreStore: InMemoryStore!
var dogListMonitor: ListMonitor<Dog>!
var dogListObjectObserver: DogListObjectObserver!
var dogObjectMonitor: ObjectMonitor<Dog>!
var dogObjectObserver: DogObjectObserver!
func go() {
internalCoreStore = initializeInternalCoreStore()
dogListObjectObserver = DogListObjectObserver(self)
dogListMonitor = CoreStore.monitorList(From<Dog>(), OrderBy<Dog>(.ascending("species")))
dogListMonitor.addObserver(dogListObjectObserver)
print("Schedule dog creation")
Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(createDog(_:)), userInfo: ["observer.dog" : "St Bernard"], repeats: false)
}
func newDogInserted(_ monitor: ListMonitor<Dog>) {
let newDog = monitor.objectsInAllSections()[0]
dogObjectMonitor = CoreStore.monitorObject(newDog)
dogObjectObserver = DogObjectObserver()
dogObjectMonitor.addObserver(dogObjectObserver)
Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(updateDog(_:)), userInfo: nil, repeats: false)
}
}
class DogListObjectObserver: ListObjectObserver {
typealias ListEntityType = Dog
func listMonitor(_ monitor: ListMonitor<Dog>, didInsertObject object: Dog, toIndexPath indexPath: IndexPath) {
print("didInsertObject")
self.database.newDogInserted(monitor)
}
func listMonitorDidChange(_ monitor: ListMonitor<Dog>) { print("list didChange") }
func listMonitorDidRefetch(_ monitor: ListMonitor<Dog>) { print("list didRefetch") }
var database: Database!
init(_ database: Database) { self.database = database }
}
class DogObjectObserver: ObjectObserver {
typealias ObjectEntityType = Dog
func objectMonitor(_ monitor: ObjectMonitor<Dog>, didUpdateObject object: Dog, changedPersistentKeys: Set<KeyPathString>) {
print("didUpdateObject")
}
}
extension Database {
@objc func createDog(_ timer: Timer) {
let userInfo = timer.userInfo! as! [String : String]
let species = userInfo["observer.dog"]!
print("in createDog for \(species)")
CoreStore.perform(
asynchronous: { (transaction) -> Void in
let dog = transaction.create(Into<Dog>())
dog.species.value = species
print("CoreStore async create new dog \(dog.species.value)")
},
completion: { _ in }
)
}
@objc func updateDog(_ timer: Timer) {
CoreStore.perform(
asynchronous: { (transaction) -> Void in
let dog = transaction.fetchOne(From<Dog>())!
dog.species.value = "Mutt"
},
completion: { _ in }
)
}
func initializeInternalCoreStore() -> InMemoryStore {
CoreStore.defaultStack = DataStack(
CoreStoreSchema(modelVersion: "Minimal", entities: [ Entity<Dog>("Dog") ])
)
return try! CoreStore.addStorageAndWait(InMemoryStore())
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment