Reputation: 2755
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!
Upvotes: 3
Views: 1747
Reputation: 2755
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 NSFetchRequest
s. 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;
}];
Upvotes: 2
Reputation: 119031
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.
Upvotes: 3