Reputation: 1334
I have RestKit set up & working properly with an API and Core Data, using an NSFetchedResultsController to display the information. All is working well, except for the deleting of local objects once they have been deleted on the server. I've tried to follow the RestKit documentation for deleting orphaned objects with RKObjectManager, but it doesn't seem to be working. Here's what I have, any insight would be great:
+ (RKMapping *)locationMapping{
//Create object map
//Same mapping as object mapping, but to NSManagedObjects
RKEntityMapping *mapping = [RKEntityMapping mappingForEntityForName:@"Location" inManagedObjectStore:[RKManagedObjectStore defaultStore]];
//Map the identical json / object properties
[mapping addAttributeMappingsFromArray:@[@"name", @"city", @"zip", @"recipient", @"street", @"state"]];
//Map the non-identical properties (left side = json, right side = NSObject)
[mapping addAttributeMappingsFromDictionary:@{
@"id": @"locationID",
@"user_id":@"userID"
}];
[mapping setIdentificationAttributes:@[@"locationID"]];
[mapping addRelationshipMappingWithSourceKeyPath:@"user" mapping:[self userMapping]];
[mapping addConnectionForRelationship:@"user" connectedBy:@"userID"];
RKObjectManager *rkObjectManager = [RKObjectManager sharedManager];
//Delete any orphaned objects
[rkObjectManager addFetchRequestBlock:^NSFetchRequest *(NSURL *URL) {
RKPathMatcher *pathMatcher = [RKPathMatcher pathMatcherWithPattern:@"/api/v1/:userID/locations"];
NSDictionary *argsDict = nil;
if ([pathMatcher matchesPath:[URL relativePath] tokenizeQueryStrings:NO parsedArguments:&argsDict]) {
NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:@"Location"];
return fetchRequest;
}
return nil;
}];
return mapping;
}
Note - the addFetchRequestBlock is not executing when the mapping is run, or an API call is made
+(void)loadUserLocations{
//Don't try to load if there is no logged in user
if(![self getCurrentUser])return;
//Create an index of successful status codes
NSIndexSet *statusCodeSet = RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful);
//Pull location mapping from Mapping Provider
RKMapping *mapping = [MappingProvider locationMapping];
//Determine how rest kit will deal with the response. Specific to API calls
RKResponseDescriptor *rkResponseDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:mapping
method:RKRequestMethodGET
pathPattern:@"/api/v1/users/:userID/locations"
keyPath:nil
statusCodes:statusCodeSet];
//Create the URL & response
NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"%@/users/%@/locations", [Statics baseURL], [self getCurrentUser].userID]];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
//Create the operation. Pass through AFHttp (more options) or NSURL
//When the request hits the path pattern (in this case, /locations),
//it will use the mapping to create the appropriate items
RKManagedObjectRequestOperation *operation = [[RKManagedObjectRequestOperation alloc] initWithRequest:request responseDescriptors:@[rkResponseDescriptor]];
//Set the cache
operation.managedObjectCache = [RKManagedObjectStore defaultStore].managedObjectCache;
operation.managedObjectContext = [RKManagedObjectStore defaultStore].mainQueueManagedObjectContext;
[operation setCompletionBlockWithSuccess:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
} failure:^(RKObjectRequestOperation *operation, NSError *error) {
NSLog(@"Error: %@", error);
NSLog(@"Response: %@", operation.HTTPRequestOperation.responseString);
}];
[operation start];
}
-(NSFetchedResultsController*)fetchedResultsController{
if (_fetchedResultsController != nil) {
return _fetchedResultsController;
}
NSFetchRequest *fetchRequest = [[RKManagedObjectStore defaultStore].managedObjectModel fetchRequestFromTemplateWithName:@"userLocations" substitutionVariables:@{@"USERID":[User getCurrentUser].userID}];
//Sort the request
NSSortDescriptor *sort = [[NSSortDescriptor alloc]
initWithKey:@"locationID" ascending:NO];
[fetchRequest setSortDescriptors:[NSArray arrayWithObject:sort]];
[fetchRequest setFetchBatchSize:20];
//Create a new controller and set it to the VC
self.fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest
managedObjectContext:self.mainMOC sectionNameKeyPath:nil
cacheName:@"Root"];
NSLog(@"%@",fetchRequest);
self.fetchedResultsController.delegate = self;
return self.fetchedResultsController;
}
Could this be a cache issue? Or am I improperly setting things up?
Upvotes: 0
Views: 927
Reputation: 119031
The path pattern /api/v1/:userID/locations
in your fetch request block doesn't match your GET request.
But your main problem is that for the fetch request block to be used the object manager needs to be running the request. As it is you're creating the request and operation explicitly and executing. You should create and configure the object manager fully and use it to make the request (which should be less code for you to write too).
Upvotes: 1