OSDN Git Service

7838876728e823d292a61ddbab066c3939b0e4f5
[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 import Doutaku
11
12 extension CoreDataProvider {
13     
14     /// 初回起動時などにデータがない時などにCoreDataを監視し値が設定される Future<T>を返す
15     ///
16     /// - Parameters:
17     ///   - block:
18     ///     Parameters: Notification (NSManagedObjectContextObjectsDidChange)
19     ///     Returns: `T?` : 成功時は `T`, エラー時は例外を発生させる。 監視を継続するときは `nil`を返す
20     /// - Returns: CoreDataの更新で値が設定される Future<T>
21     func future<T>(block: @escaping (Notification) throws -> T?) -> Future<T> {
22         
23         return NotificationCenter.default
24             .future(name: .NSManagedObjectContextObjectsDidChange, object: self.context, block: block)
25     }
26 }
27
28 extension Notification {
29     
30     struct ChangedType: OptionSet {
31         
32         let rawValue: UInt8
33         
34         static let inserted = ChangedType(rawValue: 0x0001)
35         static let updated = ChangedType(rawValue: 0x0002)
36         static let deleted = ChangedType(rawValue: 0x0004)
37     }
38     
39     func insertedManagedObjects<T: NSManagedObject>() -> [T] {
40         
41         return managedObjects(infoKey: NSInsertedObjectsKey)
42     }
43     
44     func updatedManagedObjects<T: NSManagedObject>() -> [T] {
45         
46         return managedObjects(infoKey: NSUpdatedObjectsKey)
47     }
48     
49     func deletedManagedObjects<T: NSManagedObject>() -> [T] {
50         
51         return managedObjects(infoKey: NSDeletedObjectsKey)
52     }
53     
54     func changedManagedObjects<T: NSManagedObject>(type: ChangedType) -> [T] {
55         
56         let inserted: [T] = type.contains(.inserted) ? insertedManagedObjects() : []
57         let updated: [T] = type.contains(.updated) ? updatedManagedObjects() : []
58         let deleted: [T] = type.contains(.deleted) ? deletedManagedObjects() : []
59         
60         return inserted + updated + deleted
61     }
62     
63     private func managedObjects<T: NSManagedObject>(infoKey: String) -> [T] {
64         
65         guard let userInfo = self.userInfo as? [String: Any] else {
66             
67             return []
68         }
69         
70         let inserted = userInfo[infoKey] as? Set<NSManagedObject>
71         return inserted?.compactMap({ $0 as? T }) ?? []
72     }
73 }