Setting Core Data attribute to nil with NSBatchUpdateRequest
Asked Answered
P

3

8

Is it possible to set an attribute to nil using NSBatchUpdateRequest? Passing NSNull() to propertiesToUpdate isn't working:

let unlockRequest = NSBatchUpdateRequest(entityName: "MyEntity")
unlockRequest.predicate = NSPredicate(format: "self in %@", myObjectIDs)
unlockRequest.propertiesToUpdate = ["lockDate": NSNull()]
var error: NSError?
myContext.executeRequest(unlockRequest, error: &error)
if let error = error {
    log.error("Failed to unlock: \(error)")
}

I don't get any errors, but it doesn't clear the date.

I've also tried setting it to NSExpression(forConstantValue: NSNull()), but that doesn't work either (forConstantValue argument does not accept an optional value, so I can't pass it nil.).

Petulancy answered 3/9, 2015 at 18:37 Comment(4)
Did you try NSExpression(constantValue: nil) ?Aurist
@Aurist Sadly it doesn't accept an optional value, so I can't pass it nil.Petulancy
@Petulancy did you find a solution for this?Abrams
@Abrams No I never did, in the end I had to set my lock date to a date in the past to effectively invalidate the lock (acceptable for me but I'm sure not for other situations).Petulancy
H
5

Current API allows to pass nil as a constant value.

unlockRequest.propertiesToUpdate = ["lockDate": NSExpression(forConstantValue: nil)]
Heretical answered 12/12, 2016 at 21:7 Comment(3)
I can see that the method signature now accepts Swift optionals. If this is verified to work then that would be the problem solved! NSExpression.init(forConstantValue obj: Any?)Orling
The compiler doesn't complain, but when I execute the request it throws an exception: Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Invalid string key (null) passed to propertiesToUpdate:'Gallstone
The header for NSBatchUpdateRequest.propertiesToUpdate says: "The expressions can be any NSExpression that evaluates to a scalar value."Gallstone
B
0

This seems to work correctly in Objective-C:

NSBatchUpdateRequest *batch = [[NSBatchUpdateRequest alloc] initWithEntityName:entityName];
NSExpression *value = [NSExpression expressionForConstantValue: nil];
batch.propertiesToUpdate = @{@"lockDate": value};
batch.resultType = NSUpdatedObjectsCountResultType;
NSError *error;                
NSBatchUpdateResult *results = [self.privateContext executeRequest:batch error:&error];
Bitters answered 27/4, 2016 at 0:36 Comment(0)
S
0

Old question but here is the way you do it in Swift, verified myself without any crash.

// Or Optional<Date>.none as Any
unlockRequest.propertiesToUpdate = ["lockDate": Date?.none as Any]
Septuagesima answered 10/9, 2023 at 7:16 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.