From d2c9704b26ee5b8c7894cf47974d820973a388f4 Mon Sep 17 00:00:00 2001 From: masakih Date: Fri, 27 Oct 2017 21:29:47 +0900 Subject: [PATCH] =?utf8?q?CoreData=E9=96=A2=E9=80=A3=E3=82=92=E5=88=86?= =?utf8?q?=E5=89=B2=E3=81=97=E3=81=A6=E6=95=B4=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- KCD.xcodeproj/project.pbxproj | 4 + KCD/CoreDataCore.swift | 138 ----------------------------- KCD/CoreDataManager.swift | 151 ++++++++++++++++++++++++++++++++ KCD/Entity.swift | 1 - KCD/ManagedObjectContextGenerator.swift | 48 +++------- 5 files changed, 169 insertions(+), 173 deletions(-) create mode 100644 KCD/CoreDataManager.swift diff --git a/KCD.xcodeproj/project.pbxproj b/KCD.xcodeproj/project.pbxproj index 58b46343..db179fc6 100644 --- a/KCD.xcodeproj/project.pbxproj +++ b/KCD.xcodeproj/project.pbxproj @@ -325,6 +325,7 @@ F4FF44D21FA0BB1C00039F21 /* TemporaryDataStoreAccessor.swift in Sources */ = {isa = PBXBuildFile; fileRef = F4FF44D11FA0BB1C00039F21 /* TemporaryDataStoreAccessor.swift */; }; F4FF44D41FA0BB4D00039F21 /* BookmarkDataStoreAccessor.swift in Sources */ = {isa = PBXBuildFile; fileRef = F4FF44D31FA0BB4D00039F21 /* BookmarkDataStoreAccessor.swift */; }; F4FF44D61FA0BB7200039F21 /* ResourceHistoryDataStoreAccessor.swift in Sources */ = {isa = PBXBuildFile; fileRef = F4FF44D51FA0BB7200039F21 /* ResourceHistoryDataStoreAccessor.swift */; }; + F4FF44D81FA21BF200039F21 /* CoreDataManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = F4FF44D71FA21BF200039F21 /* CoreDataManager.swift */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -707,6 +708,7 @@ F4FF44D11FA0BB1C00039F21 /* TemporaryDataStoreAccessor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TemporaryDataStoreAccessor.swift; sourceTree = ""; }; F4FF44D31FA0BB4D00039F21 /* BookmarkDataStoreAccessor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BookmarkDataStoreAccessor.swift; sourceTree = ""; }; F4FF44D51FA0BB7200039F21 /* ResourceHistoryDataStoreAccessor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ResourceHistoryDataStoreAccessor.swift; sourceTree = ""; }; + F4FF44D71FA21BF200039F21 /* CoreDataManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CoreDataManager.swift; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -1071,6 +1073,7 @@ children = ( F4BDEEB11E73FE2000D689AE /* Entity.swift */, F4E471281E46ECF1009B5AF4 /* CoreDataCore.swift */, + F4FF44D71FA21BF200039F21 /* CoreDataManager.swift */, F44AA2661E814A4400EED8BE /* ManagedObjectContextGenerator.swift */, F481D63E1F9105CB007E2CBE /* Entities.swift */, F4FC3E8D1E4368BB00E41228 /* KCManagedObject.swift */, @@ -1646,6 +1649,7 @@ F47C3EAC1E5F1AD900D97449 /* ShipMapper.swift in Sources */, F44BC7351E2A295E004644E3 /* SetActionCommand.swift in Sources */, F472159E1E1E6EE70083D3BC /* ShipMasterDetailWindowController.swift in Sources */, + F4FF44D81FA21BF200039F21 /* CoreDataManager.swift in Sources */, F44BC6D71E226CB1004644E3 /* HokyuChargeCommand.swift in Sources */, F4CF25BC1E34F67400C02A66 /* KenzoDockStatus.swift in Sources */, F44BC6F91E23DAC5004644E3 /* RealDestroyShipCommand.swift in Sources */, diff --git a/KCD/CoreDataCore.swift b/KCD/CoreDataCore.swift index 8134adde..c700d681 100644 --- a/KCD/CoreDataCore.swift +++ b/KCD/CoreDataCore.swift @@ -8,14 +8,6 @@ import Cocoa -// MARK: enum -enum CoreDataManagerType { - - case reader - case editor -} - -// MARK: - struct struct CoreDataConfiguration { let modelName: String @@ -74,133 +66,3 @@ struct CoreDataCore { return moc } } - -// MARK: - protocol -protocol CoreDataProvider { - - init(type: CoreDataManagerType) - - static var core: CoreDataCore { get } - - var context: NSManagedObjectContext { get } - - func save() - func removeDataFile() -} - -protocol CoreDataAccessor: CoreDataProvider { - - func insertNewObject(for entity: Entity) -> T? - func delete(_ object: NSManagedObject) - func object(of entity: Entity, with objectId: NSManagedObjectID) -> T? - func objects(of entity: Entity, sortDescriptors: [NSSortDescriptor]?, predicate: NSPredicate?) throws -> [T] - - func object(with objectId: NSManagedObjectID) -> NSManagedObject -} - -protocol CoreDataManager: CoreDataAccessor { - - associatedtype InstanceType = Self - - static var `default`: InstanceType { get } - - static func oneTimeEditor() -> InstanceType -} - -// MARK: - Extension -extension CoreDataProvider { - - func save() { - - if !context.commitEditing() { - - print("\(String(describing: type(of: self))) unable to commit editing before saveing") - - return - } - - do { - - try context.save() - - } catch { - - presentOnMainThread(error) - } - - if let p = context.parent { - - p.performAndWait { - do { - - try p.save() - - } catch { - - self.presentOnMainThread(error) - } - } - } - } - - func removeDataFile() { - - remove(name: type(of: self).core.config.fileName) - } - - private func presentOnMainThread(_ error: Error) { - - if Thread.isMainThread { - - NSApp.presentError(error) - - } else { - - DispatchQueue.main.sync { - - _ = NSApp.presentError(error) - } - } - } - - static func context(for type: CoreDataManagerType) -> NSManagedObjectContext { - - switch type { - case .reader: return core.parentContext - - case .editor: return core.editorContext() - } - } -} - -extension CoreDataAccessor { - - func insertNewObject(for entity: Entity) -> T? { - - return NSEntityDescription.insertNewObject(forEntityName: entity.name, into: context) as? T - } - - func delete(_ object: NSManagedObject) { - - context.delete(object) - } - - func object(of entity: Entity, with objectId: NSManagedObjectID) -> T? { - - return context.object(with: objectId) as? T - } - - func objects(of entity: Entity, sortDescriptors: [NSSortDescriptor]? = nil, predicate: NSPredicate? = nil) throws -> [T] { - - let req = NSFetchRequest(entityName: entity.name) - req.sortDescriptors = sortDescriptors - req.predicate = predicate - - return try context.fetch(req) - } - - func object(with objectId: NSManagedObjectID) -> NSManagedObject { - - return context.object(with: objectId) - } -} diff --git a/KCD/CoreDataManager.swift b/KCD/CoreDataManager.swift new file mode 100644 index 00000000..3fcf3337 --- /dev/null +++ b/KCD/CoreDataManager.swift @@ -0,0 +1,151 @@ +// +// CoreDataManager.swift +// KCD +// +// Created by Hori,Masaki on 2017/10/26. +// Copyright © 2017年 Hori,Masaki. All rights reserved. +// + +import Cocoa + +enum CoreDataManagerType { + + case reader + case editor +} + +enum CoreDataError: Error { + + case applicationDirectoryIsFile + case couldNotCreateModel + case couldNotCreateCoordinator(String) +} + +protocol CoreDataProvider { + + init(type: CoreDataManagerType) + + static var core: CoreDataCore { get } + + var context: NSManagedObjectContext { get } + + func save() + func removeDataFile() +} + +protocol CoreDataAccessor: CoreDataProvider { + + func insertNewObject(for entity: Entity) -> T? + func delete(_ object: NSManagedObject) + func object(of entity: Entity, with objectId: NSManagedObjectID) -> T? + func objects(of entity: Entity, sortDescriptors: [NSSortDescriptor]?, predicate: NSPredicate?) throws -> [T] + + func object(with objectId: NSManagedObjectID) -> NSManagedObject +} + +protocol CoreDataManager: CoreDataAccessor { + + associatedtype InstanceType = Self + + static var `default`: InstanceType { get } + + static func oneTimeEditor() -> InstanceType +} + +// MARK: - Extension +extension CoreDataProvider { + + func save() { + + if !context.commitEditing() { + + print("\(String(describing: type(of: self))) unable to commit editing before saveing") + + return + } + + do { + + try context.save() + + } catch { + + presentOnMainThread(error) + } + + if let p = context.parent { + + p.performAndWait { + do { + + try p.save() + + } catch { + + self.presentOnMainThread(error) + } + } + } + } + + func removeDataFile() { + + removeAllDataFile(named: type(of: self).core.config.fileName) + } + + private func presentOnMainThread(_ error: Error) { + + if Thread.isMainThread { + + NSApp.presentError(error) + + } else { + + DispatchQueue.main.sync { + + _ = NSApp.presentError(error) + } + } + } + + static func context(for type: CoreDataManagerType) -> NSManagedObjectContext { + + switch type { + case .reader: return core.parentContext + + case .editor: return core.editorContext() + } + } +} + +extension CoreDataAccessor { + + func insertNewObject(for entity: Entity) -> T? { + + return NSEntityDescription.insertNewObject(forEntityName: entity.name, into: context) as? T + } + + func delete(_ object: NSManagedObject) { + + context.delete(object) + } + + func object(of entity: Entity, with objectId: NSManagedObjectID) -> T? { + + return context.object(with: objectId) as? T + } + + func objects(of entity: Entity, sortDescriptors: [NSSortDescriptor]? = nil, predicate: NSPredicate? = nil) throws -> [T] { + + let req = NSFetchRequest(entityName: entity.name) + req.sortDescriptors = sortDescriptors + req.predicate = predicate + + return try context.fetch(req) + } + + func object(with objectId: NSManagedObjectID) -> NSManagedObject { + + return context.object(with: objectId) + } +} diff --git a/KCD/Entity.swift b/KCD/Entity.swift index 3fdeea4c..e20afc1e 100644 --- a/KCD/Entity.swift +++ b/KCD/Entity.swift @@ -29,7 +29,6 @@ extension EntityProvider { } } -// MARK: - Implementations extension NSManagedObject { class var entityName: String { return String(describing: self) } diff --git a/KCD/ManagedObjectContextGenerator.swift b/KCD/ManagedObjectContextGenerator.swift index 688e10eb..c77d3fb8 100644 --- a/KCD/ManagedObjectContextGenerator.swift +++ b/KCD/ManagedObjectContextGenerator.swift @@ -8,14 +8,16 @@ import Cocoa -enum CoreDataError: Error { +func genarate(_ config: CoreDataConfiguration) throws -> (model: NSManagedObjectModel, coordinator: NSPersistentStoreCoordinator, moc: NSManagedObjectContext) { + + let model = try createModel(config) + let coordinator = try getCoordinator(config, model) + let moc = createContext(coordinator) - case applicationDirectoryIsFile - case couldNotCreateModel - case couldNotCreateCoordinator(String) + return (model: model, coordinator: coordinator, moc: moc) } -func remove(name: String) { +func removeAllDataFile(named name: String) { ["", "-wal", "-shm"] .map { name + $0 } @@ -23,22 +25,6 @@ func remove(name: String) { .forEach(removeDataFile) } -func genarate(_ config: CoreDataConfiguration) throws -> (model: NSManagedObjectModel, coordinator: NSPersistentStoreCoordinator, moc: NSManagedObjectContext) { - - do { - - let model = try createModel(config) - let coordinator = try getCoordinator(config, model) - let moc = createContext(coordinator) - - return (model: model, coordinator: coordinator, moc: moc) - - } catch { - - throw error - } -} - private func removeDataFile(at url: URL) { do { @@ -62,6 +48,7 @@ private func createModel(_ config: CoreDataConfiguration) throws -> NSManagedOb return model } + private func getCoordinator(_ config: CoreDataConfiguration, _ model: NSManagedObjectModel) throws -> NSPersistentStoreCoordinator { do { @@ -75,7 +62,7 @@ private func getCoordinator(_ config: CoreDataConfiguration, _ model: NSManagedO (error.code == 134130 || error.code == 134110), config.tryRemake { - remove(name: config.fileName) + removeAllDataFile(named: config.fileName) do { @@ -83,7 +70,7 @@ private func getCoordinator(_ config: CoreDataConfiguration, _ model: NSManagedO } catch { - print("Fail crrate NSPersistentStoreCoordinator twice.") + print("Fail to create NSPersistentStoreCoordinator twice.") } } @@ -103,17 +90,10 @@ private func createCoordinator(_ config: CoreDataConfiguration, _ model: NSManag let coordinator: NSPersistentStoreCoordinator = NSPersistentStoreCoordinator(managedObjectModel: model) let url = ApplicationDirecrories.support.appendingPathComponent(config.fileName) - do { - - try coordinator.addPersistentStore(ofType: config.type, - configurationName: nil, - at: url, - options: config.options) - - } catch { - - throw error - } + try coordinator.addPersistentStore(ofType: config.type, + configurationName: nil, + at: url, + options: config.options) return coordinator } -- 2.11.0