軽量移行が失敗した場合にコアデータデータスタックを再構築しようとしており、ユーザーをログイン画面に戻しています。私はto-many関係をto-oneに変更することでこれをテストしています。コアデータの再構築/リセットエラー
最初に、新しいpersistentStoreCoordinatorを削除した後に追加するときに、同じURL(storeURL)を使用しました。しかし、 "try persistentStoreCoordinator.add ..."行のrebuildCoreData()に同じストアを2回追加できないというエラーが表示されました。
次に、新しい永続ストアのURLを変更することにしました"1"を追加することで、それはself.applicationDocumentsDirectory.URLByAppendingPathComponent( "SingleViewCoreData1.sqlite")になりました。これは正しい方向への一歩を踏み出しました。まだエラーはなく、ログイン画面に戻ることができます。しかし、ログイン後に最初の保存をしようとすると、「このNSPersistentStoreCoordinatorには永続ストアがありません(スキーマの不一致または移行の失敗)」というエラーが発生します。保存操作を実行できません。
私はここで間違っていますか?
lazy var persistentStoreCoordinator: NSPersistentStoreCoordinator = {
// The persistent store coordinator for the application. This implementation creates and returns a coordinator, having added the store for the application to it. This property is optional since there are legitimate error conditions that could cause the creation of the store to fail.
// Create the coordinator and store
let coordinator = NSPersistentStoreCoordinator(managedObjectModel: self.managedObjectModel)
let url = self.applicationDocumentsDirectory.URLByAppendingPathComponent("SingleViewCoreData.sqlite")
let options = [NSMigratePersistentStoresAutomaticallyOption: true,
NSInferMappingModelAutomaticallyOption: true]
var failureReason = "There was an error creating or loading the application's saved data."
do {
try coordinator.addPersistentStoreWithType(NSSQLiteStoreType, configuration: nil, URL: url, options: options)
} catch {
// Report any error we got.
var dict = [String: AnyObject]()
dict[NSLocalizedDescriptionKey] = "Failed to initialize the application's saved data"
dict[NSLocalizedFailureReasonErrorKey] = failureReason
dict[NSUnderlyingErrorKey] = error as NSError
let wrappedError = NSError(domain: "YOUR_ERROR_DOMAIN", code: 9999, userInfo: dict)
NSLog("Unresolved error \(wrappedError), \(wrappedError.userInfo)")
self.rebuildCoreData()
}
return coordinator
}()
lazy var managedObjectContext: NSManagedObjectContext = {
// Returns the managed object context for the application (which is already bound to the persistent store coordinator for the application.) This property is optional since there are legitimate error conditions that could cause the creation of the context to fail.
let coordinator = self.persistentStoreCoordinator
var managedObjectContext = NSManagedObjectContext(concurrencyType: .MainQueueConcurrencyType)
managedObjectContext.persistentStoreCoordinator = coordinator
managedObjectContext.mergePolicy = NSRollbackMergePolicy //This policy discards in-memory state changes for objects in conflict. The persistent store’s version of the objects’ state is used
return managedObjectContext
}()
// MARK: - Tearing down core data stack and rebuilding it in the case that a lightweight migration fails
func rebuildCoreData() {
let storeURL = self.applicationDocumentsDirectory.URLByAppendingPathComponent("SingleViewCoreData.sqlite")
do {
try NSFileManager.defaultManager().removeItemAtURL(storeURL)
} catch {
print(error)
abort()
}
for object in managedObjectContext.registeredObjects {
managedObjectContext.deleteObject(object)
}
do {
try persistentStoreCoordinator.addPersistentStoreWithType(NSSQLiteStoreType, configuration: nil, URL: storeURL, options: [NSMigratePersistentStoresAutomaticallyOption: true,
NSInferMappingModelAutomaticallyOption: true])
} catch {
print(error)
abort()
}
print("successfully rebuilt core data")
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let controller = storyboard.instantiateInitialViewController()
self.window?.rootViewController?.presentViewController(controller!, animated: false, completion: nil)
}
UPDATE - 変更されたファイルの削除とcatchブロックで、永続ストアコーディネータ・ロジックを編集し
lazy var persistentStoreCoordinator: NSPersistentStoreCoordinator = {
// The persistent store coordinator for the application. This implementation creates and returns a coordinator, having added the store for the application to it. This property is optional since there are legitimate error conditions that could cause the creation of the store to fail.
// Create the coordinator and store
var coordinator = NSPersistentStoreCoordinator(managedObjectModel: self.managedObjectModel)
let url = self.applicationDocumentsDirectory.URLByAppendingPathComponent("SingleViewCoreData.sqlite")
let options = [NSMigratePersistentStoresAutomaticallyOption: true,
NSInferMappingModelAutomaticallyOption: true]
var failureReason = "There was an error creating or loading the application's saved data."
do {
try coordinator.addPersistentStoreWithType(NSSQLiteStoreType, configuration: nil, URL: url, options: options)
} catch {
// Report any error we got.
var dict = [String: AnyObject]()
dict[NSLocalizedDescriptionKey] = "Failed to initialize the application's saved data"
dict[NSLocalizedFailureReasonErrorKey] = failureReason
dict[NSUnderlyingErrorKey] = error as NSError
let wrappedError = NSError(domain: "YOUR_ERROR_DOMAIN", code: 9999, userInfo: dict)
NSLog("Unresolved error \(wrappedError), \(wrappedError.userInfo)")
//rebuilds core data
coordinator = self.rebuildCoreData(coordinator)
}
return coordinator
}()
新rebuildCoreDataコード:
// MARK: - Tearing down core data stack and rebuilding it in the case that a lightweight migration fails
func rebuildCoreData(coordinator: NSPersistentStoreCoordinator) -> NSPersistentStoreCoordinator {
let persistentStoreParentPath = self.applicationDocumentsDirectory.path
let fileEnumerator = NSFileManager.defaultManager().enumeratorAtPath(persistentStoreParentPath!)
while let path = fileEnumerator?.nextObject() as? String {
if path.hasPrefix("SingleViewCoreData.sqlite") || path.hasPrefix(".SingleViewCoreData.sqlite") {
let pathToDelete = (persistentStoreParentPath! as NSString).stringByAppendingPathComponent(path)
do {
try NSFileManager.defaultManager().removeItemAtPath(pathToDelete)
}
catch _ {
// Handle error removing file
}
}
}
for object in managedObjectContext.registeredObjects {
managedObjectContext.deleteObject(object)
}
do {
let url = self.applicationDocumentsDirectory.URLByAppendingPathComponent("SingleViewCoreData.sqlite")
try coordinator.addPersistentStoreWithType(NSSQLiteStoreType, configuration: nil, URL: url, options: [NSMigratePersistentStoresAutomaticallyOption: true,
NSInferMappingModelAutomaticallyOption: true])
} catch {
print(error)
abort()
}
print("successfully rebuilt core data")
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let controller = storyboard.instantiateInitialViewController()
self.window?.rootViewController?.presentViewController(controller!, animated: false, completion: nil)
return coordinator
}
サンプルコードスニペットを教えてください。 また、NSPersistentStoreCoordinatorに永続ストアがない場合、2番目のエラーはどうでしたか? –
@mckamikeファイルの列挙と削除の例が必要ですか?あなたの 'CoreData'ファイルが削除された後、私は' CoreData'スタック全体を再作成します。以前に作成したコーディネーターを残しておくと、あまり節約できません。 –
あなたの質問と2番目の声明にはいっていますが、どうすれば "再作成"できますか? –