2015-02-23 72 views
0

我正试图在CoreData的两个版本之间进行迁移,这些迁移基本上与新版本具有两种配置的事实有所不同,因此我可以将实体保存在两个不同的sqlite文件(一个只读在主包中,一个是旧的sqlite,现在只用于用户数据)。我还添加了一个模型映射来映射差异,特别是重置由于多个配置而丢失的实体之间的关系。 如果从头开始安装,并且应用程序文档目录中的用户数据sqlite中插入新记录,应用程序将正常运行而不会崩溃。 问题是,当我试图从以前的核心数据版本迁移:在应用程序启动时不崩溃,但在第一次executeFetchRequest它在coordinator!.addPersistentStoreWithType(NSSQLiteStoreType, configuration: "Userdata", URL: urlUser, options: optionsUser, error: &errorUser)(含调试观看)和控制台回报崩溃此日志:关于核心数据版本迁移的“无法两次添加相同的存储”

2015-02-23 18:48:24.052 MedAbility[21480:585606] CoreData: error: -addPersistentStoreWithType:SQLite configuration:(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/Documents/MedAbility.sqlite options:{ NSInferMappingModelAutomaticallyOption = 1; NSMigratePersistentStoresAutomaticallyOption = 1; } ... returned error Error Domain=NSCocoaErrorDomain Code=134080 "The operation couldn’t be completed. (Cocoa error 134080.)" UserInfo=0x7fb50ae481d0 {NSUnderlyingException=Can't add the same store twice} with userInfo dictionary { NSUnderlyingException = "Can't add the same store twice"; } 2015-02-23 18:48:24.061 MedAbility[21480:585606] CoreData: error: -addPersistentStoreWithType:SQLite configuration: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/Documents/MedAbility.sqlite options:{ NSInferMappingModelAutomaticallyOption = 1; NSMigratePersistentStoresAutomaticallyOption = 1; } ... returned error Error Domain=NSCocoaErrorDomain Code=134080 "The operation couldn’t be completed. (Cocoa error 134080.)" UserInfo=0x7fb50ae481d0 {NSUnderlyingException=Can't add the same store twice} with userInfo dictionary { NSUnderlyingException = "Can't add the same store twice"; }

这是我的代码:

旧版本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),应用程序启动时没有问题,显然没有没有加入数据库的内容。如果我反向添加两个数据库,那么应用程序会崩溃,除了在“ex-first now-second”数据库(“MedAbilityDomande.sqlite”)上调用的“URL:file:[...]在实践中,它是增加了第二个数据库的问题,而不是一个特定的数据库。看起来,将旧数据库迁移到用于用户数据的新数据库实际上不会迁移配置,因此仍然是旧配置,它将实体与插入到mainBundle中的新只读数据库重叠。正如我之前所说的,如果应用程序从头开始(没有迁移),完美地工作。

你有什么想法吗?

非常感谢你!

回答

0

我终于找到了解决方案!我基于数据库创建了数据库MedAbilityDomande.sqlite,该数据库在我想迁移以用于用户数据之后。这带来了两个数据库具有相同的UUID,从而产生错误"Can't add the same store twice"。只需更改应用程序包(MedAbilityDomande.sqlite)中数据库的UUID即可,而且一切运行良好。

直到下一次!

+0

嗨我也面临这个问题,你是如何改变捆绑中使用的数据库的UUID? – anoop4real 2016-03-08 08:59:39

+0

嗨!我用一个软件来打开数据库(我使用“DB Browser for SQLite”)。然后我手动更改了表“Z_METADATA”的列“Z_UUID”上的UUID字符串。为了确保使用有效且唯一的UUID,我创建了一个带有临时应用程序的新CoreData数据库,然后始终使用“DB Browser for SQLite”,将UUID从新数据库复制并粘贴到我想要的数据库包括在包中。 – 2016-03-10 10:01:15

+0

非常感谢,我需要尝试一下 – anoop4real 2016-03-10 10:35:36

相关问题