CoreDataの変化をNotificationで監視するのは結構面倒臭い。
例えばこうなる。
普通にやるやつ
class Object: NSManagedObject {}
上のObject
に何か変化があった時何かするスケルトン
NotificatioCenter.default
.addObserver(forName: .NSManagedObjectContextObjectsDidChange, object: managedObjectContext, queue: .main) { notification in
guard let userInfo = notification.userInfo else {
return
}
let inserted = userInfo[NSInsertedObjectsKey] as? Set<NSManagedObject>
inserted
.flatMap { $0 as? Object }
.forEach {
// do something
}
let updated = userInfo[NSUpdatedObjectsKey] as? Set<NSManagedObject>
updated
.flatMap { $0 as? Object }
.forEach {
// do something
}
let deleted = userInfo[NSDeletedObjectsKey] as? Set<NSManagedObject>
deleted
.flatMap { $0 as? Object }
.forEach {
// do something
}
}
ながい!!
スケルトンなのに超長い!!!
楽にするやつ
なので楽にするやつを作った。
extension Notification {
struct ChangedType: OptionSet {
let rawValue: UInt8
static let inserted = ChangedType(rawValue: 0x0001)
static let updated = ChangedType(rawValue: 0x0002)
static let deleted = ChangedType(rawValue: 0x0004)
static let all = ChangedType(rawValue: 0x0007)
}
func insertedManagedObjects<T: NSManagedObject>() -> [T] {
return managedObjects(infoKey: NSInsertedObjectsKey)
}
func updatedManagedObjects<T: NSManagedObject>() -> [T] {
return managedObjects(infoKey: NSUpdatedObjectsKey)
}
func deletedManagedObjects<T: NSManagedObject>() -> [T] {
return managedObjects(infoKey: NSDeletedObjectsKey)
}
func changedManagedObjects<T: NSManagedObject>(type: ChangedType = .all) -> [T] {
let inserted: [T] = type.contains(.inserted) ? insertedManagedObjects() : []
let updated: [T] = type.contains(.updated) ? updatedManagedObjects() : []
let deleted: [T] = type.contains(.deleted) ? deletedManagedObjects() : []
return inserted + updated + deleted
}
private func managedObjects<T: NSManagedObject>(infoKey: String) -> [T] {
guard let userInfo = self.userInfo as? [String: Any] else { return [] }
let inserted = userInfo[infoKey] as? Set<NSManagedObject>
return inserted?.flatMap({ $0 as? T }) ?? []
}
}
これを使うとスケルトンはこうなる。
NotificatioCenter.default
.addObserver(forName: .NSManagedObjectContextObjectsDidChange, object: managedObjectContext, queue: .main) { notification in
notification
.insertedManagedObjects()
.forEach { (objcct: Object) in
// do some
}
notification
.updatedManagedObjects()
.forEach { (objcct: Object) in
// do some
}
notification
.deletedManagedObjects()
.forEach { (objcct: Object) in
// do some
}
}
ちょっとだけ短くなった。
がんばりましょう
型を確定するのが面倒くさい
もうちょっとどうにかしたい