2 // ManagedObjectContextGenerator.swift
5 // Created by Hori,Masaki on 2017/03/21.
6 // Copyright © 2017年 Hori,Masaki. All rights reserved.
11 final class MOCGenerator {
13 let config: CoreDataConfiguration
15 init(_ config: CoreDataConfiguration) {
20 func genarate() throws -> (model: NSManagedObjectModel, coordinator: NSPersistentStoreCoordinator, moc: NSManagedObjectContext) {
22 let model = try createModel()
23 let coordinator = try createCoordinator(model)
24 let moc = createContext(coordinator)
26 return (model: model, coordinator: coordinator, moc: moc)
29 private func removeDataFile() {
32 .map { config.fileName + $0 }
33 .map(ApplicationDirecrories.support.appendingPathComponent)
37 private func removeFile(at url: URL) {
41 try FileManager.default.removeItem(at: url)
45 print("Could not remove file for URL (\(url))")
49 // MARK: - NSManagedObjectContext and ...
50 private func createModel() throws -> NSManagedObjectModel {
52 guard let modelURL = Bundle.main.url(forResource: config.modelName, withExtension: "momd"),
53 let model = NSManagedObjectModel(contentsOf: modelURL) else {
55 throw CoreDataError.couldNotCreateModel
61 private func isMigrationError(_ code: Int) -> Bool {
63 NSPersistentStoreIncompatibleVersionHashError,
65 NSMigrationConstraintViolationError,
66 NSMigrationCancelledError,
67 NSMigrationMissingSourceModelError,
68 NSMigrationMissingMappingModelError,
69 NSMigrationManagerSourceStoreError,
70 NSMigrationManagerDestinationStoreError,
71 NSEntityMigrationPolicyError
75 private func createCoordinator(_ model: NSManagedObjectModel) throws -> NSPersistentStoreCoordinator {
77 if !checkDirectory(ApplicationDirecrories.support, create: true) {
79 throw CoreDataError.saveLocationIsUnuseable
84 return try makeCoordinator(model)
86 } catch let error as NSError {
88 // Data Modelが更新されていたらストアファイルを削除してもう一度
89 if error.domain == NSCocoaErrorDomain,
90 isMigrationError(error.code),
97 return try makeCoordinator(model)
101 print("Fail to create NSPersistentStoreCoordinator twice.")
105 throw CoreDataError.couldNotCreateCoordinator(error.localizedDescription)
109 private func makeCoordinator(_ model: NSManagedObjectModel) throws -> NSPersistentStoreCoordinator {
111 let coordinator: NSPersistentStoreCoordinator = NSPersistentStoreCoordinator(managedObjectModel: model)
112 let url = ApplicationDirecrories.support.appendingPathComponent(config.fileName)
113 try coordinator.addPersistentStore(ofType: config.type,
114 configurationName: nil,
116 options: config.options)
121 private func createContext(_ coordinator: NSPersistentStoreCoordinator) -> NSManagedObjectContext {
123 let moc = NSManagedObjectContext(concurrencyType: .mainQueueConcurrencyType)
124 moc.persistentStoreCoordinator = coordinator
125 moc.undoManager = nil