2 // CoreDataManager.swift
5 // Created by Hori,Masaki on 2017/10/26.
6 // Copyright © 2017年 Hori,Masaki. All rights reserved.
11 enum CoreDataManagerType {
17 enum CoreDataError: Error {
19 case saveLocationIsUnuseable
20 case couldNotCreateModel
21 case couldNotCreateCoordinator(String)
22 case couldNotSave(String)
25 protocol CoreDataProvider {
27 init(type: CoreDataManagerType)
29 static var core: CoreDataCore { get }
31 var context: NSManagedObjectContext { get }
33 func save(errorHandler: (Error) -> Void)
37 protocol CoreDataAccessor: CoreDataProvider {
39 func insertNewObject<T>(for entity: Entity<T>) -> T?
40 func delete(_ object: NSManagedObject)
41 func object<T>(of entity: Entity<T>, with objectId: NSManagedObjectID) -> T?
42 func objects<T>(of entity: Entity<T>, sortDescriptors: [NSSortDescriptor]?, predicate: NSPredicate?) throws -> [T]
44 func object(with objectId: NSManagedObjectID) -> NSManagedObject
47 protocol CoreDataManager: CoreDataAccessor {
49 associatedtype InstanceType = Self
51 static var `default`: InstanceType { get }
53 static func oneTimeEditor() -> InstanceType
57 extension CoreDataProvider {
59 static func context(for type: CoreDataManagerType) -> NSManagedObjectContext {
62 case .reader: return core.parentContext
64 case .editor: return core.editorContext()
68 func save(errorHandler: (Error) -> Void) {
82 guard context.commitEditing() else {
84 throw CoreDataError.couldNotSave("\(String(describing: type(of: self))) unable to commit editing before saveing")
91 } catch let error as NSError {
93 throw CoreDataError.couldNotSave(error.localizedDescription)
96 guard let parent = context.parent else { return }
98 // save parent context
99 var catchedError: NSError? = nil
100 parent.performAndWait {
106 } catch let error as NSError {
112 if let error = catchedError {
114 throw CoreDataError.couldNotSave(error.localizedDescription)
119 func presentOnMainThread(_ error: Error) {
121 if Thread.isMainThread {
123 NSApp.presentError(error)
127 DispatchQueue.main.sync {
129 _ = NSApp.presentError(error)
135 extension CoreDataAccessor {
137 func insertNewObject<T>(for entity: Entity<T>) -> T? {
139 return NSEntityDescription.insertNewObject(forEntityName: entity.name, into: context) as? T
142 func delete(_ object: NSManagedObject) {
144 context.delete(object)
147 func object<T>(of entity: Entity<T>, with objectId: NSManagedObjectID) -> T? {
149 return context.object(with: objectId) as? T
152 func objects<T>(of entity: Entity<T>, sortDescriptors: [NSSortDescriptor]? = nil, predicate: NSPredicate? = nil) throws -> [T] {
154 let req = NSFetchRequest<T>(entityName: entity.name)
155 req.sortDescriptors = sortDescriptors
156 req.predicate = predicate
158 return try context.fetch(req)
161 func object(with objectId: NSManagedObjectID) -> NSManagedObject {
163 return context.object(with: objectId)