Home > Blockchain >  SwiftUI & Unit test fails: Can't add the same store twice when using core data stack
SwiftUI & Unit test fails: Can't add the same store twice when using core data stack

Time:06-01

After updating Xcode to 13.4 my core data persistence stack started to fail for SwiftUI previews and Xcode Unit tests.

Error message:

Unresolved error Error Domain=NSCocoaErrorDomain Code=134081 "(null)" UserInfo={NSUnderlyingException=Can't add the same store twice}, ["NSUnderlyingException": Can't add the same store twice ...

Persistence stack:

struct PersistenceController {
    static let shared = PersistenceController()

    let container: NSPersistentContainer

    init(inMemory: Bool = false) {
        container = NSPersistentContainer(name: "Persistence")
        if inMemory {
            container.persistentStoreDescriptions.first!.url = URL(fileURLWithPath: "/dev/null")
        }
        let description = NSPersistentStoreDescription()

        description.shouldInferMappingModelAutomatically = true
        description.shouldMigrateStoreAutomatically = true

        container.persistentStoreDescriptions.append(description)
        container.loadPersistentStores(completionHandler: { (storeDescription, error) in
            if let error = error as NSError? {
                fatalError("Unresolved error \(error), \(error.userInfo)")
            }
        })
        container.viewContext.automaticallyMergesChangesFromParent = true
    }
}

Usage for SwiftUI previews:

struct MyScreen_Previews: PreviewProvider {
    static var previews: some View {
        MyScreen()
            .environment(\.managedObjectContext, PersistenceController.preview.container.viewContext)
    }
}

Extension to support SwiftUI preview:

extension PersistenceController {
    static var preview: PersistenceController = {
        let result = PersistenceController(inMemory: true)
        // Pre-fill core data with required information for preview.
    }
}

CodePudding user response:

There's a mistake in your code, when you append to the array of descriptions you now have 2 descriptions.

Change it to:

let description = container.persistentStoreDescriptions.first!
description.shouldInferMappingModelAutomatically = true
description.shouldMigrateStoreAutomatically = true

// Load

CodePudding user response:

I noticed, that after loading persistence storage error generated. This error (Can't add the same store twice), can be ignored for SwiftUI previews and Unit Tests.

To ignore this type of error needs to check XCTestSessionIdentifier and XCODE_RUNNING_FOR_PREVIEWS in the process info.

if let error = error as NSError? {
    if ProcessInfo.processInfo.environment["XCTestSessionIdentifier"] == nil && 
       ProcessInfo.processInfo.environment["XCODE_RUNNING_FOR_PREVIEWS"] == nil {
        fatalError("Unresolved error \(error), \(error.userInfo)")
    }
}
  • Related