"不能两次添加同一商店"关于Core Data版本的迁移

时间:2015-02-23 18:09:59

标签: ios swift core-data core-data-migration

我正在尝试在两个版本的CoreData之间执行迁移,这与新版本有两个配置的事实根本不同,因此我可以将实体保存在两个不同的sqlite文件中(一个只读在主捆绑中,一个,旧的sqlite,现在只用于用户数据)。我还添加了一个模型映射来映射差异,尤其是重置由于多个配置而丢失的实体之间的关系。 如果从头开始安装,应用程序可正常运行而不会崩溃,并且应用程序文档目录中的用户数据sqlite中会按预期插入新记录。 问题是当我尝试从以前的Core Data版本迁移时:应用程序启动时没有崩溃但是在executeFetchRequest它崩溃在coordinator!.addPersistentStoreWithType(NSSQLiteStoreType, configuration: "Userdata", URL: urlUser, options: optionsUser, error: &errorUser)(用debug查看)并且控制台返回此日志:

  

2015-02-23 18:48:24.052 MedAbility [21480:585606] CoreData:错误:   -addPersistentStoreWithType:SQLite配置:(null)URL:file:/// Volumes / Documenti / Users / andrea / Library / Developer / CoreSimulator / Devices / 301801BE-4B6A-4371-BE66-3E71557B0897 / data / Containers / Data / Application / FBEC0124-1D74-4F94-99F2-6F492281AA8E /文档/ MedAbility.sqlite   选项:{       NSInferMappingModelAutomaticallyOption = 1;       NSMigratePersistentStoresAutomaticallyOption = 1; } ...返回错误错误Domain = NSCocoaErrorDomain Code = 134080"操作   无法完成。 (可可错误134080。)"的UserInfo = 0x7fb50ae481d0   使用userInfo {NSUnderlyingException = 无法将同一商店添加两次}   字典{       NSUnderlyingException =" 无法两次添加同一商店&#34 ;; 2015-02-23 18:48:24.061 MedAbility [21480:585606] CoreData:错误:   -addPersistentStoreWithType:SQLite配置:Userdata URL:file:/// Volumes / Documenti / Users / andrea / Library / Developer / CoreSimulator / Devices / 301801BE-4B6A-4371-BE66-3E71557B0897 / data / Containers / Data / Application / FBEC0124- 1D74-4F94-99F2-6F492281AA8E /文档/ MedAbility.sqlite   选项:{       NSInferMappingModelAutomaticallyOption = 1;       NSMigratePersistentStoresAutomaticallyOption = 1; } ...返回错误错误Domain = NSCocoaErrorDomain Code = 134080"操作   无法完成。 (可可错误134080。)"的UserInfo = 0x7fb50ae481d0   使用userInfo {NSUnderlyingException = 无法将同一商店添加两次}   字典{       NSUnderlyingException =" 无法两次添加同一商店&#34 ;; }

这是我的代码:

旧版PersistentStoreCoordinator:

lazy var persistentStoreCoordinator: NSPersistentStoreCoordinator? = {
        // Create the coordinator and store
        var coordinator: NSPersistentStoreCoordinator? = NSPersistentStoreCoordinator(managedObjectModel: self.managedObjectModel)
        let url = self.applicationDocumentsDirectory.URLByAppendingPathComponent("MedAbility.sqlite")
        var error: NSError? = nil
        var failureReason = "There was an error creating or loading the application's saved data."
        // Set options for migrations
        let options = [NSMigratePersistentStoresAutomaticallyOption: true, NSInferMappingModelAutomaticallyOption: true]
        if coordinator!.addPersistentStoreWithType(NSSQLiteStoreType, configuration: nil, URL: url, options: options, error: &error) == nil {
            coordinator = nil
            // Report any error we got.
            let dict = NSMutableDictionary()
            dict[NSLocalizedDescriptionKey] = "Failed to initialize the application's saved data"
            dict[NSLocalizedFailureReasonErrorKey] = failureReason
            dict[NSUnderlyingErrorKey] = error
            error = NSError(domain: "YOUR_ERROR_DOMAIN", code: 9999, userInfo: dict)

            NSLog("Unresolved error \(error), \(error!.userInfo)")
        }

        // Exclude db from backup
        Util.addSkipBackupAttributeToItemAtURL(url)

        return coordinator
        }()

新版PersistentStoreCoordinator:

lazy var persistentStoreCoordinator: NSPersistentStoreCoordinator? = {
        // The persistent store coordinator for the application. This implementation creates and return 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? = NSPersistentStoreCoordinator(managedObjectModel: self.managedObjectModel)

        let url = NSBundle.mainBundle().URLForResource("MedAbilityDomande", withExtension: "sqlite")
        var error: NSError? = nil
        var failureReason = "There was an error creating or loading the application's saved data."
        // Set questions sqlite as read-only
        let options = [NSReadOnlyPersistentStoreOption: true]
        if coordinator!.addPersistentStoreWithType(NSSQLiteStoreType, configuration: "Domande", URL: url, options: options, error: &error) == nil {
            coordinator = nil
            // Report any error we got.
            let dict = NSMutableDictionary()
            dict[NSLocalizedDescriptionKey] = "Failed to initialize the application's saved data"
            dict[NSLocalizedFailureReasonErrorKey] = failureReason
            dict[NSUnderlyingErrorKey] = error
            error = NSError(domain: "YOUR_ERROR_DOMAIN", code: 9999, userInfo: dict)

            NSLog("Unresolved error \(error), \(error!.userInfo)")
        }

        let urlUser = self.applicationDocumentsDirectory.URLByAppendingPathComponent("MedAbility.sqlite")
        var errorUser: NSError? = nil
        var failureReasonUser = "There was an error creating or loading the application's saved data."
        // Set migration options
        let optionsUser = [NSMigratePersistentStoresAutomaticallyOption: true, NSInferMappingModelAutomaticallyOption: true]
        if coordinator!.addPersistentStoreWithType(NSSQLiteStoreType, configuration: "Userdata", URL: urlUser, options: optionsUser, error: &errorUser) == nil {
            coordinator = nil
            // Report any error we got.
            let dict = NSMutableDictionary()
            dict[NSLocalizedDescriptionKey] = "Failed to initialize the application's saved data"
            dict[NSLocalizedFailureReasonErrorKey] = failureReasonUser
            dict[NSUnderlyingErrorKey] = errorUser
            errorUser = NSError(domain: "YOUR_ERROR_DOMAIN", code: 9999, userInfo: dict)

            NSLog("Unresolved error \(errorUser), \(errorUser!.userInfo)")
        }

        return coordinator
        }()

有人知道我该如何解决这个问题?

感谢您的帮助!

修改

我做了一些测试,我发现为第一个数据库评论coordinator!.addPersistentStoreWithType (NSSQLiteStoreType, configuration: "Questions", URL: url, options: options, error: & error),应用程序启动没有问题,显然没有添加数据库的内容。如果我反向添加两个数据库,应用程序会崩溃同样的日志,除了" URL:file:[...]"它被称为ex-first now-second数据库(" MedAbilityDomande.sqlite");在实践中,第二个数据库是问题而不是特定数据库的添加。似乎将旧数据库迁移到用于用户数据的新数据库实际上并不会迁移配置,因此保留旧配置,使实体与插入mainBundle的新只读数据库重叠。正如我之前所说过的,如果应用程序从头开始(没有迁移)可以完美运行。

你有什么想法吗?

再次感谢你!

1 个答案:

答案 0 :(得分:0)

我终于找到了解决方案!我根据数据库创建了数据库MedAbilityDomande.sqlite,在我想要迁移以用于用户数据之后。这使得两个具有相同UUID的数据库生成错误"Can't add the same store twice"。在应用程序包(MedAbilityDomande.sqlite)中更改数据库的UUID就足够了,一切都很顺利。

直到下一次!