Search code examples
iosobjective-crestrestkit

RestKit: How to reject an entire mapping when a value is not valid


So I'm trying to support offline usage of an iOS application I'm making that uses a REST API. Here's what I have so far:

  • A server running with a REST interface to manipulate my data model.
  • An iOS application that uses RestKit to retrieve the data stored on my server.
  • RestKit stores server responses locally in Core Data.

When the server is unavailable I still want users to be able to update the data model and then when the server becomes available again I want those updates to be pushed to the server.

The issue I've run into is that when a value that has been updated locally (but not pushed to the server yet) is received from the server it is overwritten with the contents of the server's response. To prevent this I am trying to cancel the save to my local storage if the new 'updatedAt' date is before the current 'updatedAt' date.

This is my current validation function:

- (BOOL)validateUpdatedAt:(id *)ioValue error:(NSError **)outError
{
    if(self.updatedAt && [self.updatedAt compare:((NSDate *)*ioValue)] == NSOrderedDescending) {

        *outError = [NSError errorWithDomain:RKErrorDomain code:RKMappingErrorMappingDeclined userInfo:nil];

        return NO;
    }
    return YES;
}

This works, but only prevents this individual value from being changed. I want the entire update of that object to be canceled if this one field is invalid. How do I do this?


Solution

  • The support available from RestKit is to set discardsInvalidObjectsOnInsert for the whole object to be discarded when validation fails. But, this won't work for you as it only works for NSManagedObject instances that are being inserted, because it uses validateForInsert:.

    You could look at using validateForUpdate: to perform a similar check and then reverting the changes, but RestKit isn't really offering you anything in terms of the abort in your case.