Reputation: 1924
My application uses RestKit to GET from a URL, the payload of which contains a list of objects (hospitals) in JSON. The first time I hit the URL, everything works fine - the payload is correctly transformed into a group of Hospital
managed objects and they are inserted into the persistent store (verified by performing a fetch request and comparing the results with the payload).
If I perform the GET a second time from the same URL, returning the same payload, RestKit inserts another group of Hospital
objects (identical to the first group) into the persistent store. I would like RestKit to determine that the second group of Hospital
objects are identical to the first, and then update the first group of objects if necessary.
The payload contains a unique identifier called provider_number
.
I added a provider_number
field to the Hospital
model and ticked Indexed
.
I set the identification attribute on the RKEntityMapping
accordingly:
+ (RKEntityMapping *) hospitalMapping {
RKEntityMapping *mapping = [RKEntityMapping mappingForEntityForName:@"Hospital" inManagedObjectStore:[RKManagedObjectStore defaultStore]];
[mapping setIdentificationAttributes:@[ @"provider_number"]];
[mapping addAttributeMappingsFromDictionary:[self hospitalAttributeDictionary]];
return mapping;
}
I created the managed object cache on the RKManagedObjectStore
, using the persistent MOC, per http://restkit.org/api/latest/Classes/RKManagedObjectRequestOperation.html#overview:
managedObjectStore.managedObjectCache = [[RKInMemoryManagedObjectCache alloc] initWithManagedObjectContext:managedObjectStore.persistentStoreManagedObjectContext];
The RKObjectManager
is configured to use the persistent MOC:
RKManagedObjectStore *managedObjectStore = [RKManagedObjectStore defaultStore];
NSManagedObjectContext *managedObjectContext = [managedObjectStore persistentStoreManagedObjectContext];
RKObjectManager *objectManager = [RKObjectManager managerWithBaseURL:url];
objectManager.managedObjectStore = managedObjectStore;
The RKObjectManager
is further configured with the response descriptor and the requested response MIME type.
The mapping operation is then enqueued:
[objectManager getObjectsAtPath:@""
parameters:nil
success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
NSError *executeError = nil;
if([managedObjectContext saveToPersistentStore:&executeError]) {
NSLog(@"Saved hospitals to persistent store.");
}
else {
NSLog(@"Failed to save to data store");
}
} failure:^(RKObjectRequestOperation *operation, NSError *error) {
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"An Error Has Occurred" message:[error localizedDescription] delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
[alertView show];
}];
Executing this twice causes duplicate object in the persistent store. What am I missing?
Upvotes: 1
Views: 867
Reputation: 119031
From this log:
restkit.core_data:RKFetchRequestManagedObjectCache.m:124 Found objects '( )' using fetchRequest ' (entity: Hospital; predicate: (provider_number == nil); sortDescriptors: ((null)); type: NSManagedObjectResultType; )'
Restkit is looking for an existing item, but the predicate is wrong: predicate: (provider_number == nil)
It immediately isn't clear why. Put a breakpoint in RKFetchRequestManagedObjectCache.m
at the start of managedObjectsWithEntity:attributeValues:inManagedObjectContext:
and check back up the stack to find out what attributeValues
is being created with and why the provider_number
isn't being completed correctly.
Upvotes: 1