2 // CoreDataProviderExtension.swift
5 // Created by Hori,Masaki on 2018/01/21.
6 // Copyright © 2018年 Hori,Masaki. All rights reserved.
11 extension CoreDataProvider {
13 /// 初回起動時などにデータがない時などにCoreDataを監視し値が設定される Future<T>を返す
17 /// Parameters: Notification (NSManagedObjectContextObjectsDidChange)
18 /// Returns: `T?` : 成功時は `T`, エラー時は例外を発生させる。 監視を継続するときは `nil`を返す
19 /// - Returns: CoreDataの更新で値が設定される Future<T>
20 func future<T>(block: @escaping (Notification) throws -> T?) -> Future<T> {
22 return NotificationCenter.default
23 .future(name: .NSManagedObjectContextObjectsDidChange, object: self.context, block: block)
27 extension Notification {
29 struct ChangedType: OptionSet {
33 static let inserted = ChangedType(rawValue: 0x0001)
34 static let updated = ChangedType(rawValue: 0x0002)
35 static let deleted = ChangedType(rawValue: 0x0004)
38 func insertedManagedObjects<T: NSManagedObject>() -> [T] {
40 return managedObjects(infoKey: NSInsertedObjectsKey)
43 func updatedManagedObjects<T: NSManagedObject>() -> [T] {
45 return managedObjects(infoKey: NSUpdatedObjectsKey)
48 func deletedManagedObjects<T: NSManagedObject>() -> [T] {
50 return managedObjects(infoKey: NSDeletedObjectsKey)
53 func changedManagedObjects<T: NSManagedObject>(type: ChangedType) -> [T] {
55 let inserted: [T] = type.contains(.inserted) ? insertedManagedObjects() : []
56 let updated: [T] = type.contains(.updated) ? updatedManagedObjects() : []
57 let deleted: [T] = type.contains(.deleted) ? deletedManagedObjects() : []
59 return inserted + updated + deleted
62 private func managedObjects<T: NSManagedObject>(infoKey: String) -> [T] {
64 guard let userInfo = self.userInfo as? [String: Any] else { return [] }
66 let inserted = userInfo[infoKey] as? Set<NSManagedObject>
67 return inserted?.flatMap({ $0 as? T }) ?? []