Swiftui&单位测试失败:使用核心数据堆栈时可以两次添加同一商店

发布于 2025-02-03 21:27:26 字数 1781 浏览 2 评论 0原文

将Xcode更新为13.4后,我的核心数据持久性堆栈开始在SwiftUI预览和Xcode单元测试中失败。

错误消息:

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 ...

持久性堆栈:

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
    }
}

Swiftui预览的用法:

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

支持Swiftui预览的扩展名:

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

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.
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

[浮城] 2025-02-10 21:27:26

代码中存在一个错误,当您附加到描述数组时,您现在有2个描述。

将其更改为:

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

// Load

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
亣腦蒛氧 2025-02-10 21:27:26

我注意到,加载持久性存储错误产生后。此错误(不能两次添加同一商店),对于SwiftUI预览和单位测试,可以忽略。

要忽略此类型的错误,需要检查 XctestSessionIdentifier Xcode_running_for_previews 在过程信息中。

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)")
    }
}

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)")
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文