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 static func removeDataFile(_ config: CoreDataConfiguration) {
32 .map { config.fileName + $0 }
33 .map(ApplicationDirecrories.support.appendingPathComponent)
37 private static 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 createCoordinator(_ model: NSManagedObjectModel) throws -> NSPersistentStoreCoordinator {
63 if !checkDirectory(ApplicationDirecrories.support) {
65 throw CoreDataError.saveLocationIsUnuseable
70 return try makeCoordinator(model)
72 } catch (let error as NSError) {
74 // Data Modelが更新されていたらストアファイルを削除してもう一度
75 if error.domain == NSCocoaErrorDomain,
76 (error.code == 134130 || error.code == 134110),
79 MOCGenerator.removeDataFile(config)
83 return try makeCoordinator(model)
87 print("Fail to create NSPersistentStoreCoordinator twice.")
91 throw CoreDataError.couldNotCreateCoordinator(error.localizedDescription)
95 private func makeCoordinator(_ model: NSManagedObjectModel) throws -> NSPersistentStoreCoordinator {
97 let coordinator: NSPersistentStoreCoordinator = NSPersistentStoreCoordinator(managedObjectModel: model)
98 let url = ApplicationDirecrories.support.appendingPathComponent(config.fileName)
99 try coordinator.addPersistentStore(ofType: config.type,
100 configurationName: nil,
102 options: config.options)
107 private func createContext(_ coordinator: NSPersistentStoreCoordinator) -> NSManagedObjectContext {
109 let moc = NSManagedObjectContext(concurrencyType: .mainQueueConcurrencyType)
110 moc.persistentStoreCoordinator = coordinator
111 moc.undoManager = nil