Вопрос

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.

Это было полезно?

Решение

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.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top