10

Hi i have updated RestKit from 0.10.2 to 0.20.3. After updating now when objects are missing from web service, RestKit not deleting them from local storage. I know it is supported in RestKit 0.20.x, but i am not being able to configure it. I followed the example given here. http://restkit.org/api/latest/Classes/RKManagedObjectRequestOperation.html#overview

I also followed similar questions on Stackoverflow. But there is no accepted answer yet.

Here is my Json

{
    "status": "Success",
    "member_info": [
        {
            "family_id": "1",
            "user_id": "1"
        },
        {
            "family_id": "2",
            "user_id": "1"
        },
        {
            "family_id": "3",
            "user_id": "1"
        }
    ]
}

Which returns all Family members for a particular user. Above Json is for user_id = 1. Now i want if request is sent for user_id = 2, then all the previous 3 objects should be deleted from local storage, as they are now missing from Json. Here is the new Json for user_id = 2

{
    "status": "Success",
    "member_info": [
        {
            "family_id": "4",
            "user_id": "2"
        },
        {
            "family_id": "5",
            "user_id": "2"
        }        
    ]
}

This is how i am creating mapping.

[objectManager addResponseDescriptorsFromArray:@[                                                                                                                  
                                                     [RKResponseDescriptor responseDescriptorWithMapping:[self connectionsMapping]
                                                                                                  method:RKRequestMethodPOST
                                                                                             pathPattern:@"familylist"
                                                                                                 keyPath:@"member_info" statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)]];



[objectManager addFetchRequestBlock:^NSFetchRequest *(NSURL *URL) {
        RKPathMatcher *pathMatcher = [RKPathMatcher pathMatcherWithPattern:@"familylist"];
        NSDictionary *argsDict = nil;
        BOOL match = [pathMatcher matchesPath:[URL relativePath] tokenizeQueryStrings:NO parsedArguments:&argsDict];
        if (match) {
            NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:@"DBConnections"];
            NSPredicate *predicate = [NSPredicate predicateWithFormat:@"user_id == %@", [DBUser currentUser].user_id];
            fetchRequest.predicate = predicate;
            fetchRequest.sortDescriptors = @[ [NSSortDescriptor sortDescriptorWithKey:@"first_name" ascending:YES] ];
            return fetchRequest;
        }

        return nil;
    }];


- (RKEntityMapping *)connectionsMapping {   
    RKEntityMapping *connectionsMapping = [RKEntityMapping mappingForEntityForName:@"DBConnections" inManagedObjectStore:objectManager.managedObjectStore];
    connectionsMapping.setDefaultValueForMissingAttributes = NO;
    connectionsMapping.identificationAttributes = @[@"family_id"];
    [connectionsMapping addAttributeMappingsFromDictionary:@{
                                                             @"family_id": @"family_id",
                                                             @"user_id": @"user_id",
                                                             }];

    return connectionsMapping;
}

In predicate i am using [DBUser currentUser].user_id, which returns the current logged in user_id. And here is i am calling the web service

[[RKObjectManager sharedManager] postObject:nil path:@"familylist" parameters:params
                                            success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
NSLog(@"Objects are %@", mappingResult.array);
}];

I am using postObject instead of getObjectsAtPath, because server is expecting POST request method. Am i doing wrong? or need to do something else for deleting orphan objects. Any help is appreciated.

Khawar
  • 9,151
  • 9
  • 46
  • 67
  • 1
    Did you debug the value of `[DBUser currentUser].user_id`? The predicate shouldn't really be required, did you try without a predicate? – Wain Nov 13 '13 at 11:02
  • Thanks @Wain, i was looking for you :), i did debug the value for predicate and i was fine, let me try without predicate. – Khawar Nov 13 '13 at 11:05
  • Still same even without predicate, the previous data is not deleted. – Khawar Nov 13 '13 at 11:10
  • I think i need to set "deletesOrphanedObjects" to true, but don't know how to do it, any suggestion about this attribute? – Khawar Nov 13 '13 at 11:19

1 Answers1

11

Finally solved the problem by debugging RestKit step by step and found this code in RKManagedObjectRequestOperation.m

if (! [[self.HTTPRequestOperation.request.HTTPMethod uppercaseString] isEqualToString:@"GET"]) {
        RKLogDebug(@"Skipping deletion of orphaned objects: only performed for GET requests.");
        return YES;
    }

Oh! RestKit doesn't delete orphan objects when the request method is POST. I changed the web services the accept GET request too and it worked perfectly. Secondly i was using predicate

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"user_id == %@", [DBUser currentUser].user_id];

It was wrong, to delete all objects except current user, i had to append NOT operator, like this

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"user_id != %@", [DBUser currentUser].user_id];

So predicate doesn't mean what you want, but it is what you don't want.

Khawar
  • 9,151
  • 9
  • 46
  • 67
  • May I just add a comment, after three year... The predicate doesnt mean either "what you want to remove" or "what you want" it means, more or less "all object expected in the request", and then all the objects in the results are substracted from that set. – netdigger Aug 22 '16 at 15:41