3

I'd like to use RESTKit not in the default way, which as far as I understand, is to update the cached objects by looking at unique IDs and either adding objects to the cache when new IDs are found or purging objects from the cache when old IDs exist.

What I'd like to do instead is always fetch objects from a URL endpoint, set the cache with these new objects, removing all the previous existing cached objects. The thing is that my JSON doesn't have any unique IDs.

Is it possible to do this? I unsuccessfully tried removing the objects in the cache before calling for new objects. Before I try too many other things, I thought I'd ask here first if there is a standard way of doing this in RESTKit.

Thanks in advance!

herrtim
  • 2,697
  • 1
  • 26
  • 36

2 Answers2

3

Yes, you can. You wouldn't want to use unique ids anyway for what you describe (though it would work if you did, but you may be left with some old data in your updated objects).

Anyway, omit any unique id from your mapping and specify a fetch request block (section Fetch Request Blocks and Deleting Orphaned Objects) that simply fetches all of the instances of your entity (no predicate). This will cause RestKit to delete all of the old objects and save all new objects during the mapping.

Your test of deleting all of the objects before making the request should work so long as you update the correct context and save it correctly.

Wain
  • 118,658
  • 15
  • 128
  • 151
  • My JSON does not have unique IDs so no need for me to omit it. My fetch request block does not have a predicate and fetches all entities. So, given this, RestKit is deleting all objects and saving new ones? Maybe the problem is then in not updating the table view correctly. If I do a "pull down" on the table view, the newly fetched entities area ADDED to the table view, and not replacing. I guess I should really somehow determine if the Core Data entities are really being deleted and if it's a display issue... – herrtim Nov 11 '13 at 21:44
  • Are you using a fetched results controller? Log the changes in the delegate callbacks. – Wain Nov 11 '13 at 21:55
  • Yes, I am using a `NSFetchedResultsController`. Can you provide some code for logging the changes please? – herrtim Nov 11 '13 at 22:04
  • 1
    `NSLog(@"%@ was %@", anObject, (type == NSFetchedResultsChangeDelete ? @"deleted" : @"added");` – Wain Nov 11 '13 at 22:31
  • Thanks. When I log in the `didChangeObject` I only see `added` and never `deleted`. Note that this problem is only occurring during a 'pull down'. I'll edit my question appropriately. – herrtim Nov 13 '13 at 08:50
  • I posted to the RestKit Google Group a revised version of my above question: https://groups.google.com/forum/#!topic/restkit/RhBeS8x0vOM – herrtim Nov 13 '13 at 10:14
  • Does that mean it works for some other request? Show your code for the request, mappings and fetch request block. Have you debugged to check the fetch request block operation? – Wain Nov 13 '13 at 10:54
2

As Wain said, the way to do this is to use a RKFetchRequestBlock. I'm not 100% sure what's going on in the section Fetch Request Blocks and Deleting Orphaned Objects RKManagedObjectRequestOperation, but in my case, all I needed to do was return a NSFetchRequest for each matched path. Since I have three endpoints in my app and three entities, I needed to have three separate pattern matching checks and return 3 unique NSFetchRequests. From what I understand, the manager will automatically consult the fetch request blocks and perform orphaned object cleanup if a NSFetchRequest is returned.

Here's my code:

RKObjectManager *objectManager = [RKObjectManager managerWithBaseURL:baseURL];

    // To perform local orphaned object cleanup
    [objectManager addFetchRequestBlock:^NSFetchRequest *(NSURL *URL) {

        RKPathMatcher *pathMatcherLeft = [RKPathMatcher pathMatcherWithPattern:@"/api/app/left.json"];
        BOOL matchLeft = [pathMatcherLeft matchesPath:[URL relativePath] tokenizeQueryStrings:NO parsedArguments:nil];
        RKPathMatcher *pathMatcherRight = [RKPathMatcher pathMatcherWithPattern:@"/api/app/right.json"];
        BOOL matchRight = [pathMatcherRight matchesPath:[URL relativePath] tokenizeQueryStrings:NO parsedArguments:nil];
        RKPathMatcher *pathMatcherCenter = [RKPathMatcher pathMatcherWithPattern:@"/api/app/center.json"];
        BOOL matchCenter = [pathMatcherCenter matchesPath:[URL relativePath] tokenizeQueryStrings:NO parsedArguments:nil];
        if (matchLeft) {
            NSLog(@"Pattern matched left.json!");
            NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:@"LeftViewItem"];
            return fetchRequest;
        }else if (matchRight) {
                NSLog(@"Pattern matched right.json!");
                NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:@"RightViewItem"];
                return fetchRequest;
        }else if (matchCenter) {
            NSLog(@"Pattern matched center.json!");
            NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:@"CenterViewItem"];
            return fetchRequest;
        }
        return nil;
    }];
Community
  • 1
  • 1
herrtim
  • 2,697
  • 1
  • 26
  • 36