Question

I am using the following to delete objects using RestKit (0.23.1):

[self.objectManager deleteObject:myObject path:path parameters:nil success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
    NSLog(@"success deleting myObject");
} failure:^(RKObjectRequestOperation *operation, NSError *error) {
    NSLog(@"failure deleting myObject");
}];

This does create the correct DELETE request and the server returns a 200 status code. However, the local data is not deleted from Core Data. If I do a fetch for the deleted object after the success block above is fired, the fetch returns the object that should be deleted.

The documentation reads:

RKManagedObjectRequestOperation adds special behavior to DELETE requests. Upon retrieving a successful (2xx status code) response for a DELETE, the operation will invoke deleteObject: with the operations targetObject on the managed object context. This will delete the target object from the local store in conjunction the successfully deleted remote representation.

Doing a little spelunking it looks like -[RKManagedObjectRequestOperation deleteTargetObject:] is not being called. It seems that it should be called by -[RKManagedObjectRequestOperation willFinish].

It seems like there may be a logic error in the gating if statement in -[RKManagedObjectRequestOperation willFinish].

- (void)willFinish
{
    NSMutableIndexSet *deleteableStatusCodes = [NSMutableIndexSet indexSet];
    [deleteableStatusCodes addIndex:404]; // Not Found
    [deleteableStatusCodes addIndex:410]; // Gone
    if (self.error && self.targetObjectID
        && [[[self.HTTPRequestOperation.request HTTPMethod] uppercaseString] isEqualToString:@"DELETE"]
        && [deleteableStatusCodes containsIndex:self.HTTPRequestOperation.response.statusCode]) {
        NSError *error = nil;
        if (! [self deleteTargetObject:&error]) {
            RKLogWarning(@"Secondary error encountered while attempting to delete target object in response to 404 (Not Found) or 410 (Gone) status code: %@", error);
            self.error = error;
        } else {
            if (! [self saveContext:&error]) {

            } else {
                // All good, clear any errors
                self.error = nil;
            }
        }
    }
}

It seems like -[RKManagedObjectRequestOperation willFinish] should be as follows:

- (void)willFinish
{
    NSMutableIndexSet *deleteableStatusCodes = [NSMutableIndexSet indexSet];
    [deleteableStatusCodes addIndex:404]; // Not Found
    [deleteableStatusCodes addIndex:410]; // Gone
    [deleteableStatusCodes addIndexes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)];
    if (self.error == nil
        && self.targetObjectID
        && [[[self.HTTPRequestOperation.request HTTPMethod] uppercaseString] isEqualToString:@"DELETE"]
        && [deleteableStatusCodes containsIndex:self.HTTPRequestOperation.response.statusCode]) {
        NSError *error = nil;
        if (! [self deleteTargetObject:&error]) {
            RKLogWarning(@"Secondary error encountered while attempting to delete target object in response to 404 (Not Found) or 410 (Gone) status code: %@", error);
            self.error = error;
        } else {
            if (! [self saveContext:&error]) {

            } else {
                // All good, clear any errors
                self.error = nil;
            }
        }
    }
}

To summarize the changes, I added the successful status codes to the deleteableStatusCodes index set and check to make sure that self.error is equal to nil.

Is my logic change sound, or am I misunderstanding some RestKit convention here? It seems like my logic change aligns with the quoted statement from the documentation.

Était-ce utile?

La solution

You're looking in the wrong place. See the line:

success = [weakSelf deleteTargetObject:&error];

In the performMappingOnResponseWithCompletionBlock: method in RKManagedObjectRequestOperation which checks for success status and deletes the object.

The code you have edited is to deal with error responses which, in a nice REST interface, mean the same thing as a DELETE success response.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top