0
votes

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.

1
The error message Can't add the same store twice is pretty clear. You are mixing up pre-iOS10 (addPersistentStore) and iOS10 code (loadPersistentStores()) which causes to add the persistent store twice. Use only one of the patterns to setup the Core data stackvadian
@vadian ahh ok - so if i remove one of the two all will be fine. Which one should I keep? or does it not matter too much?ZiEiTiA
It does matter, If you keep addPersistentStore you have to implement other properties so it's easier to keep loadPersistentStores. Delete the myFileManager line and the entire following do - catch block.vadian
@vadian - will it manage the migration using the migration model automatically then?ZiEiTiA
The core data code is equal to the Core Data stack. It's mandatory to handle the Core Data communication. Create a new project in Xcode and check the Core Data check box. Xcode will create the code to create the Core Data stack for you.vadian

1 Answers

1
votes

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 find