Swift 5.x
In 2022, consider using NSBatchInsertRequest
to insert batch data into persist store.
⚠️ Warning: NSBatchRequest will not post Notification. If you using observer to detect data change, you must handle batch request manual.
Create Batch Insert Request
Assume CustomMO
is target NSManagedObject, and here's code sample
// Load all data from JSON file
var jsonData: [CustomObjectData] = loadData()
func createBatchInsertRequest() -> NSBatchInsertRequest {
// Create an iterator for raw data
var itemListIterator = jsonData.makeIterator()
let batchInserRequest = NSBatchInsertRequest(entity: CustomMO.entity()) { (obj: NSManagedObject) in
// Stop add item when itemListIterator return nil
guard let item = itemListIterator.next() else { return true }
// Convert obj to CustomMO type and fill data to obj
if let cmo = obj as? CustomMO {
cmo.name = item.name
cmo.description = item.description
}
// Continue add item to batch insert request
return false
}
return batchInserRequest
}
Execute Request
You can choose directly execute request or run it in background
var container: NSPersistentContainer!
let request = createBatchInsertRequest()
// Directly Execute
do {
try container.viewContext.execute(request)
} catch {
// Log Error Here
}
// Execute In background
container.performBackgroundTask { context in
do {
try context.execute(request)
} catch {
// Log Error Here
}
}
Extra Steps Refresh Row Cache
The code below from here
request.resultType = .objectIDs
let result = try! context.execute(request)
let resultInsert = result as? NSBatchInsertResult
if let objectIDs = resultInsert?.result as? [NSManagedObjectID], !objectIDs.isEmpty {
let save = [NSInsertedObjectsKey: objectIDs]
NSManagedObjectContext.mergeChanges(fromRemoteContextSave: save, into: [mainContext])
}