Search code examples
iossqlitecore-dataswift3

NSUnderlyingException = "Can't add the same store twice" when migrating core data


I am setting up my apps persistent container with the following code:

lazy var persistentContainer: NSPersistentContainer = {
    let container = NSPersistentContainer(name: "App_Name")

    let myFileManager = FileManager()

    do {
        let docsurl = try myFileManager.url(for:.applicationSupportDirectory, in: .userDomainMask, appropriateFor: nil, create: false)

        let myUrl = docsurl.appendingPathComponent("App_Name")

        let description = NSPersistentStoreDescription(url: myUrl)
        container.persistentStoreDescriptions = [description]

        let options = [NSInferMappingModelAutomaticallyOption : true,
                        NSMigratePersistentStoresAutomaticallyOption : true]

        try container.persistentStoreCoordinator.addPersistentStore(ofType: NSInMemoryStoreType, configurationName: nil, at: myUrl, options: options)

    } catch {
        fatalErrorText = error.localizedDescription
        print(fatalErrorText)
    }

    container.loadPersistentStores(completionHandler: { (storeDescription, error) in
        if let error = error as NSError? {
            fatalErrorText = error.debugDescription
            print(fatalErrorText)
        }
    })
    return container
}()

However when I try and access core Data it get the following error:

2017-08-07 14:43:57.391529+0100 App Name[98764:1854740] [error] error: -addPersistentStoreWithType:SQLite configuration:(null) URL:file:///Users/Seb/Library/Developer/CoreSimulator/Devices/241E1A36-631B-4071-8357-5F551F32403F/data/Containers/Data/Application/BC35D1CD-FA17-4F1F-99A0-EB0E73A42F3C/Library/Application%20Support/App_Name.sqlite options:{ NSInferMappingModelAutomaticallyOption = 1; NSMigratePersistentStoresAutomaticallyOption = 1; } ... returned error Error Domain=NSCocoaErrorDomain Code=134080 "(null)" UserInfo={NSUnderlyingException=Can't add the same store twice} with userInfo dictionary { NSUnderlyingException = "Can't add the same store twice"; } CoreData: error: -addPersistentStoreWithType:SQLite configuration:(null) URL:file:///Users/Seb/Library/Developer/CoreSimulator/Devices/241E1A36-631B-4071-8357-5F551F32403F/data/Containers/Data/Application/BC35D1CD-FA17-4F1F-99A0-EB0E73A42F3C/Library/Application%20Support/App_Name.sqlite options:{ NSInferMappingModelAutomaticallyOption = 1; NSMigratePersistentStoresAutomaticallyOption = 1; } ... returned error Error Domain=NSCocoaErrorDomain Code=134080 "(null)" UserInfo={NSUnderlyingException=Can't add the same store twice} with userInfo dictionary { NSUnderlyingException = "Can't add the same store twice"; }

I have got iCloud enabled, and did find an answer that was claiming the problem was with iCloud, but their solution didn't work for me.

I have found a few other solutions to this problem on here but haven't been able to decipher/translate the answers.


Solution

  • A NSPersistentContainer is a wrapper for all you need for a core-data stack. It will create a managedObjectContext with a persistentStoreCoordinator setup with a single sql store. It is simplified to find the model with they name that you give it, and name the sql file with the same name. Automatic migration is turned on by default for an NSPersistentContainer.

    If you need a more custom setup, you can either create all the entities yourself (which is not that hard). Or you can set the persistentStoreDescriptions property before you call loadPersistentStores. With a persistentStoreDescription you can set the URL to save the sql file to, and set shouldMigrateStoreAutomatically. Generally there is no reason to to as it is set to true by default see https://developer.apple.com/documentation/coredata/nspersistentstoredescription/1640566-shouldmigratestoreautomatically

    TL;DR get rid of everything in the do catch, the default behavior of loadPersistentStores will work fine.