Core Data Batch insert

394 views Asked by At

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

0

There are 0 answers