Give something like this a try:
func syncLocations() {
var batchCreate: [[String: Any]] = []
for location in remoteLocations {
if let objectID = locationDataSource.performFetchObjectID(Location.requestLocationStruct(location)) {
let updateObj = locationDataSource.updateContext.object(with: objectID) as! Location
let (latitude, longitude) = invalidCoordinates(updateObj.provider, updateObj.slug)
updateObj.latitude = latitude
updateObj.longitude = longitude
locationDataSource.saveUpdateObject()
} else {
let (latitude, longitude) = invalidCoordinates(location.provider, location.slug!)
batchCreate.append(
[
"uniqueID": UUID().uuidString,
"title": location.title,
"name": location.name ?? "",
"slug": location.slug ?? "",
"subtitle": location.subtitle ?? "",
"locale": location.locale ?? "",
"provider": location.provider,
"latitude": latitude,
"longitude": longitude
])
}
}
let request = NSBatchInsertRequest(entityName: Location.entityName, objects: batchCreate)
locationDataSource.performBatchInsert(request, "location")
}
...
func performBatchInsert(_ request: NSBatchInsertRequest, _ author: String = appTransactionAuthorName) {
do {
createContext.transactionAuthor = author
try createContext.executeAndMergeChanges(using: request)
} catch {
print(error)
}
}
extension NSManagedObjectContext {
public func executeAndMergeChanges(using batchInsertRequest: NSBatchInsertRequest) throws {
batchInsertRequest.resultType = .objectIDs
let result = try execute(batchInsertRequest) as! NSBatchInsertResult
let changes: [AnyHashable: Any] = [NSInsertedObjectsKey: result.result as? [NSManagedObjectID] ?? []]
NSManagedObjectContext.mergeChanges(fromRemoteContextSave: changes, into: [self])
}
}
The batch insert request basically wants an array of objects that are themselves an array of property key-values. As such, you'll need to make sure the JSON decodes to [[String: Any]]