OSDN Git Service

CoreData関連を変更
[kcd/KCD.git] / KCD / ManagedObjectContextGenerator.swift
1 //
2 //  ManagedObjectContextGenerator.swift
3 //  KCD
4 //
5 //  Created by Hori,Masaki on 2017/03/21.
6 //  Copyright © 2017年 Hori,Masaki. All rights reserved.
7 //
8
9 import Cocoa
10
11 final class MOCGenerator {
12     
13     let config: CoreDataConfiguration
14     
15     init(_ config: CoreDataConfiguration) {
16         
17         self.config = config
18     }
19     
20     func genarate() throws -> (model: NSManagedObjectModel, coordinator: NSPersistentStoreCoordinator, moc: NSManagedObjectContext) {
21         
22         let model = try createModel()
23         let coordinator = try createCoordinator(model)
24         let moc = createContext(coordinator)
25         
26         return (model: model, coordinator: coordinator, moc: moc)
27     }
28     
29     static func removeDataFile(_ config: CoreDataConfiguration) {
30         
31         ["", "-wal", "-shm"]
32             .map { config.fileName + $0 }
33             .map(ApplicationDirecrories.support.appendingPathComponent)
34             .forEach(removeFile)
35     }
36     
37     private static func removeFile(at url: URL) {
38         
39         do {
40             
41             try FileManager.default.removeItem(at: url)
42             
43         } catch {
44             
45             print("Could not remove file for URL (\(url))")
46         }
47     }
48     
49     // MARK: - NSManagedObjectContext and ...
50     private func createModel() throws -> NSManagedObjectModel {
51         
52         guard let modelURL = Bundle.main.url(forResource: config.modelName, withExtension: "momd"),
53             let model = NSManagedObjectModel(contentsOf: modelURL) else {
54                 
55                 throw CoreDataError.couldNotCreateModel
56         }
57         
58         return model
59     }
60     
61     private func createCoordinator(_ model: NSManagedObjectModel) throws -> NSPersistentStoreCoordinator {
62         
63         if !checkDirectory(ApplicationDirecrories.support) {
64             
65             throw CoreDataError.saveLocationIsUnuseable
66         }
67         
68         do {
69             
70             return try makeCoordinator(model)
71             
72         } catch (let error as NSError) {
73             
74             // Data Modelが更新されていたらストアファイルを削除してもう一度
75             if error.domain == NSCocoaErrorDomain,
76                 (error.code == 134130 || error.code == 134110),
77                 config.tryRemake {
78                 
79                 MOCGenerator.removeDataFile(config)
80                 
81                 do {
82                     
83                     return try makeCoordinator(model)
84                     
85                 } catch {
86                     
87                     print("Fail to create NSPersistentStoreCoordinator twice.")
88                 }
89             }
90             
91             throw CoreDataError.couldNotCreateCoordinator(error.localizedDescription)
92         }
93     }
94     
95     private func makeCoordinator(_ model: NSManagedObjectModel) throws -> NSPersistentStoreCoordinator {
96         
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,
101                                            at: url,
102                                            options: config.options)
103         
104         return coordinator
105     }
106     
107     private func createContext(_ coordinator: NSPersistentStoreCoordinator) -> NSManagedObjectContext {
108         
109         let moc = NSManagedObjectContext(concurrencyType: .mainQueueConcurrencyType)
110         moc.persistentStoreCoordinator = coordinator
111         moc.undoManager = nil
112         
113         return moc
114     }
115 }