5

I'm trying to insert Array of dictionary in CoreData using NSBatchInsertRequest according WWDC 2019 (https://developer.apple.com/videos/play/wwdc2019/230/). The insertResult is nil, and my CoreData is empty.

let modelURL = Bundle.main.url(forResource: "CoreDataPerformance", withExtension: "momd")!
let model = NSManagedObjectModel(contentsOf: modelURL)!
let container = NSPersistentCloudKitContainer(name: "CoreDataPerformance", managedObjectModel: model)
container.loadPersistentStores(completionHandler: { (storeDescription, error) in
    if let error = error as NSError? {
        fatalError("Unresolved error \(error), \(error.userInfo)")
    }
})

try container.viewContext.setQueryGenerationFrom(.current)

let moc = container.viewContext
moc.automaticallyMergesChangesFromParent = true
moc.perform {
    let insertRequest = NSBatchInsertRequest(entity: Client.entity(), objects: clients)
    let insertResult = try? moc.execute(insertRequest) as? NSBatchInsertRequest
    let success = insertResult?.resultType
    print("RESULT STATUS: \(success)")
}

This is the error I receive in the console:

2020-02-04 18:30:25.800705+0200 CoreDataPerformance[62836:778869] [error] warning: Multiple NSEntityDescriptions claim the NSManagedObject subclass 'CoreDataPerformance.Client' so +entity is unable to disambiguate.

CoreData: warning: Multiple NSEntityDescriptions claim the NSManagedObject subclass 'CoreDataPerformance.Client' so +entity is unable to disambiguate.

2020-02-04 18:30:25.800846+0200 CoreDataPerformance[62836:778869] [error] warning:   'Client' (0x600000c50bb0) from NSManagedObjectModel (0x600001877480) claims 'CoreDataPerformance.Client'.

CoreData: warning:   'Client' (0x600000c50bb0) from NSManagedObjectModel (0x600001877480) claims 'CoreDataPerformance.Client'.

2020-02-04 18:30:25.800940+0200 CoreDataPerformance[62836:778869] [error] warning:   'Client' (0x600000c589a0) from NSManagedObjectModel (0x600001861680) claims 'CoreDataPerformance.Client'.

CoreData: warning:   'Client' (0x600000c589a0) from NSManagedObjectModel (0x600001861680) claims 'CoreDataPerformance.Client'.
benhi
  • 574
  • 1
  • 6
  • 24
  • The four lines in your call to `moc.perform`... have you attempted to run these without embedding in this perform closure - that is - delete the call to `perform`? – andrewbuilder Feb 05 '20 at 23:26

4 Answers4

1

your line let insertResult = try? moc.execute(insertRequest) as? NSBatchInsertRequest

should be: let insertResult = try? moc.execute(insertRequest) as? NSBatchInsertResult

andre
  • 88
  • 2
  • 5
0

The disambiguation issue is because you have multiple core data stacks open while the app is running. Is this because you have your app and a stack for tests? or because your app is using more than one?

Samuel Goodwin
  • 1,698
  • 13
  • 17
0

The error CoreData: warning: Multiple NSEntityDescriptions claim the NSManagedObject subclass 'CoreDataPerformance.Client' so +entity is unable to disambiguate. means you have multiple entities in your model using the Client NSManagedObject subclass, there should only be one.

Another issue with your code is automaticallyMergesChangesFromParent does not work with batch requests because no did save notification is generated. You have to use NSPersistentStoreRemoteChangeNotification, NSPersistentHistoryChangeRequest and mergeChangesFromContextDidSaveNotification the technique is explained in WWDC 2018 Core Data Best Practices @ 21:57

malhal
  • 26,330
  • 7
  • 115
  • 133
-3

I think there's an error in the WWDC talk. Try doing this:

let insertRequest = NSBatchInsertRequest(entity: Client.entity(), objects: clients)
try! moc.execute(insertRequest)
try! moc.save()

I used try! just so I can see any error. You can change it

libranner
  • 1
  • 1
  • 3
    NSBatchInsertRequest saves the object into the persistent store. I think you don't need to save the context explicitly. https://developer.apple.com/documentation/coredata/nsbatchinsertrequest – iCoder Mar 17 '21 at 04:02