Core Data Batch insert
Updated:28.11.2022 20:24 (at the end of this post)
i have 150 rows from entity #1 now i need to insert for each single row from entity #1 (SingleOnes) 20 rows into entity #2 (Packs)
pattern:
row1: count 1, object 1 row2: count 2, object 1 row3: count 3, object 1 (...) row21: count 1, object 2 row22: count 2, object 2 row23: count 3, object 2 and so on at the moment i can only do this with creating an array of objects for entity #2 (3000 rows), and save them simply with context.save()
// sOne:[SingleOnes] // fetched rows from SingleOnes entity // create Packs sOne.forEach { one in for x in 1...20 { let newPack = Packs(context: context) newPack.count = Int16(x) newPack.addToUsedSingleOnes(one) } } context.performAndWait { do { try context.save() } catch let error { print(error.localizedDescription) } } but as i have doubts about the reliability of this method i rather want to insert those 3000 rows with a batch insert instead, and i cannot find the right way to do so..
i hand over an array to this function containing all objects from entity #1
func newBatchInsertSWRequest(with singleOnes: [SingleOnes]) -> NSBatchInsertRequest { var index = 0 let total = singleOnes.count // this is the wrong count and it does not work withs singleOnes.count*20 as well let batchInsert = NSBatchInsertRequest( entity: Packs.entity()) { (managedObject: NSManagedObject) -> Bool in guard index < total else { return true } for x in 1...20 { if let newPack = managedObject as? Packs { let data = singleOnes[index] newPack.count = Int16(x) newPack.addToUsedSingleOnes(data) // (...) } } index += 1 return false } return batchInsert } i've tried to many variants of this function but i never managed to create the correct amount of 3000 rows.. any ideas?
Updated:28.11.2022 20:24
func newBatchInsertWPRequest(with singleOnes: [SingleOnes]) -> NSBatchInsertRequest { var index = 0 let total = 3000 let batchInsert = NSBatchInsertRequest( entity: Packs.entity()) { (managedObject: NSManagedObject) -> Bool in guard index < total else { return true } for x in 1...20 { if let newPack = managedObject as? Packs { let data = singleOnes[index] newPack.count = Int16(x) newPack.addToUsedSingleOnes(data) } index += 1 } return false } return batchInsert } Terminating app due to uncaught exception 'NSRangeException', reason: '*** __boundsFail: index 150 beyond bounds [0 .. 149]' terminating with uncaught exception of type NSException seems like i can't do it this way...the function expects the amount to be the count of the array given...
i will have to give an array with all 3000 objects to that function.. hm..
total(as your code comment mentions). That comes from the argument you pass in, so it's external, but your batch request depends on it.