OSDN Git Service

Notificationのエクステンションを追加
[kcd/KCD.git] / KCD / CoreDataProviderExtension.swift
1 //
2 //  CoreDataProviderExtension.swift
3 //  KCD
4 //
5 //  Created by Hori,Masaki on 2018/01/21.
6 //  Copyright © 2018年 Hori,Masaki. All rights reserved.
7 //
8
9 import Cocoa
10
11 extension CoreDataProvider {
12     
13     /// 初回起動時などにデータがない時などにCoreDataを監視し値が設定される Future<T>を返す
14     ///
15     /// - Parameters:
16     ///   - block:
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> {
21         
22         return NotificationCenter.default
23             .future(name: .NSManagedObjectContextObjectsDidChange, object: self.context, block: block)
24     }
25 }
26
27 extension Notification {
28     
29     struct ChangedType: OptionSet {
30         
31         let rawValue: UInt8
32         
33         static let inserted = ChangedType(rawValue: 0x0001)
34         static let updated = ChangedType(rawValue: 0x0002)
35         static let deleted = ChangedType(rawValue: 0x0004)
36     }
37     
38     func insertedManagedObjects<T: NSManagedObject>() -> [T] {
39         
40         return managedObjects(infoKey: NSInsertedObjectsKey)
41     }
42     
43     func updatedManagedObjects<T: NSManagedObject>() -> [T] {
44         
45         return managedObjects(infoKey: NSUpdatedObjectsKey)
46     }
47     
48     func deletedManagedObjects<T: NSManagedObject>() -> [T] {
49         
50         return managedObjects(infoKey: NSDeletedObjectsKey)
51     }
52     
53     func changedManagedObjects<T: NSManagedObject>(type: ChangedType) -> [T] {
54         
55         let inserted: [T] = type.contains(.inserted) ? insertedManagedObjects() : []
56         let updated: [T] = type.contains(.updated) ? updatedManagedObjects() : []
57         let deleted: [T] = type.contains(.deleted) ? deletedManagedObjects() : []
58         
59         return inserted + updated + deleted
60     }
61     
62     private func managedObjects<T: NSManagedObject>(infoKey: String) -> [T] {
63         
64         guard let userInfo = self.userInfo as? [String: Any] else { return [] }
65         
66         let inserted = userInfo[infoKey] as? Set<NSManagedObject>
67         return inserted?.flatMap({ $0 as? T }) ?? []
68     }
69 }