3
votes

I am trying to use NSBatchUpdateRequest to update a one-to-many relationship.

My entity, Presentation, has multiple Slide, which is another entity, and they have an inverse relationship.

enter image description here enter image description here

When I try to update slides, I get this error:

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Invalid relationship ((), name slides, isOptional 1, isTransient 0, entity Presentation, renamingIdentifier slides, validation predicates ( ), warnings ( ), versionHashModifier (null) userInfo { }, destination entity Slide, inverseRelationship presentation, minCount 0, maxCount 0, isOrdered 0, deleteRule 1) passed to propertiesToUpdate:'

I've tried to search for this error, but couldn't find any results.

My code:

let entity = NSEntityDescription.entityForName("Presentation", inManagedObjectContext: managedObjectContext)
let batchRequest = NSBatchUpdateRequest(entity: entity!)
batchRequest.resultType = .UpdatedObjectIDsResultType
batchRequest.propertiesToUpdate = ["date_updated": formattedDateUpdated, "slides": presentationSlides]

do {
      let batchUpdateResult = try managedObjectContext.executeRequest(batchRequest) as! NSBatchUpdateResult
      let objectIds = batchUpdateResult.result as! [NSManagedObjectID]

      for objectId in objectIds {
          let managedObject = managedObjectContext.objectWithID(objectId)

          managedObjectContext.refreshObject(managedObject, mergeChanges: false)
      }
 } catch {
          let updateError = error as NSError
          print(updateError)
 }

date_updated updated just fine, so I don't think this is the correct way of updating a relationship.

If anyone needs more code, please let me know. Thanks for any help.

1
Why are you using NSBatchUpdateRequest? That will update every Presentation with the new date_updated and slides. Is that what you want?pbasdf
@pbasdf No. I could use the fetch, update and save way, that would be only update the Presentation I want right? First time using Core Data so I'm not sure.sallyp
Yes - an ordinary NSFetchRequest (with a predicate to fetch only the Presentation you want), then update the date_updated attribute, and the slides relationship, then save, should do the trick.pbasdf
Thank you. I will try that for myself. I am still curious about this question in particular too. I will try @Alex Kosyakov 's solution also. (Thanks Alex)sallyp

1 Answers

3
votes

I think you need to separate this batch request for two, one is for Presentation class instances:

let entity = NSEntityDescription.entityForName("Presentation", inManagedObjectContext: managedObjectContext)
let batchRequest = NSBatchUpdateRequest(entity: entity!)
batchRequest.resultType = .UpdatedObjectIDsResultType
batchRequest.propertiesToUpdate = ["date_updated": formattedDateUpdated]

The second is for Slides class instances, that you can filter using predicate:

let entity = NSEntityDescription.entityForName("Slide", inManagedObjectContext: managedObjectContext)
let batchRequest = NSBatchUpdateRequest(entity: entity!)
batchRequest.resultType = .UpdatedObjectIDsResultType
batchRequest.predicate = NSPredicate(format: "presentation = %@ \(somePresentation)");
batchRequest.propertiesToUpdate = ["some_property": newValue]