首页 > 解决方案 > CoreData 错误:必须在初始化期间提供获取请求

问题描述

我的所有 CoreData UnitTests 都有以下代码设置(context我的viewContextItemCoreData 模型在哪里):

override func setUpWithError() throws {
    let deleteReq = NSBatchDeleteRequest(fetchRequest: Item.fetchRequest())
    try context.execute(deleteReq)
}

现在,我在声明时收到此错误deleteReq

必须在初始化期间提供获取请求 (NSInvalidArgumentException)

我这样设置我的控制器:

let testController = PersistenceController(inMemory: true)

// #### - ####

init(inMemory: Bool = false) {
    container = NSPersistentCloudKitContainer(name: "AppName")
    if inMemory {
        container.persistentStoreDescriptions.first!.url = URL(fileURLWithPath: "/dev/null")
    }
    
    container.viewContext.automaticallyMergesChangesFromParent = true
    container.viewContext.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy
    container.loadPersistentStores(completionHandler: { (storeDescription, error) in
        // [...]
        return
    })
}

难道我做错了什么?

标签: ioscore-datansmanagedobjectcontextnsfetchrequestnspersistentcloudkitcontainer

解决方案


ETA:这实际上并没有帮助‍♂️我将两个不同的问题混为一谈,这个答案解决了另一个问题。对不起。如果您找到问题的答案,请 lmk。我也会这样做。


我今天也遇到了这个问题-几乎完全相同的设置,所以希望对我有用的方法会对您有所帮助。

事实证明,这与我试图将我的上下文纳入测试的方式有关,这使得错误消息非常具有误导性。我在我的 dataController 中添加了一个主上下文的属性,并在我的测试中引用了它,它现在可以工作了。

在应用程序中,DataController.swift(我还必须将此文件添加到测试目标):

class DataController: ObservableObject {
    let container: NSPersistentCloudKitContainer
    let moc: NSManagedObjectContext

    init(inMemory: Bool = false) {
        container = NSPersistentCloudKitContainer(name: "Main") // or "AppName"
    
        if inMemory {
            container.persistentStoreDescriptions.first?.url = URL(fileURLWithPath: "/dev/null")
        }
    
        container.loadPersistentStores { (storeDescription, error) in
            if let error = error {
                fatalError("Fatal error loading store: \(error.localizedDescription)")
            }
        }
    
        moc = container.viewContext
    }

    ...

    func deleteAll() {
        let fetchRequest: NSFetchRequest<NSFetchRequestResult> = EntityName.fetchRequest()
        let batchDeleteRequest = NSBatchDeleteRequest(fetchRequest: fetchRequest)
        _ = try? container.viewContext.execute(batchDeleteRequestSteps)
    }
}

在我的测试中:

class SomeTests: XCTestCase {

    var dataController = DataController()

    override func setUpWithError() throws {
        let context: NSManagedObjectContext = dataController.moc
        dataController.deleteAll()
        let entityTestObj = EntityName(context: context)
        
        // some setup stuff here

        dataController.save()
    }

    // ... actual tests here
}

推荐阅读