Reputation: 5605
I'm trying to sync my local core data database with a remote JSON API. I'm using RestKit to map JSON values into local managed objects. here is a piece of code:
- (IBAction)testButtonPressed:(id)sender {
NSManagedObjectModel *managedObjectModel = [NSManagedObjectModel mergedModelFromBundles:nil];
RKManagedObjectStore *managedObjectStore = [[RKManagedObjectStore alloc] initWithManagedObjectModel:managedObjectModel];
NSError *error = nil;
BOOL success = RKEnsureDirectoryExistsAtPath(RKApplicationDataDirectory(), &error);
if (! success) {
RKLogError(@"Failed to create Application Data Directory at path '%@': %@", RKApplicationDataDirectory(), error);
}
// - - - - - - - - Change the path !
NSString *path = [RKApplicationDataDirectory() stringByAppendingPathComponent:@"AC.sqlite"];
NSPersistentStore *persistentStore = [managedObjectStore addSQLitePersistentStoreAtPath:path
fromSeedDatabaseAtPath:nil
withConfiguration:nil
options:nil
error:&error];
if (! persistentStore) {
RKLogError(@"Failed adding persistent store at path '%@': %@", path, error);
}
[managedObjectStore createManagedObjectContexts];
// - - - - - - - - Here we change keys and values
RKEntityMapping *placeMapping = [RKEntityMapping mappingForEntityForName:@"Place"
inManagedObjectStore:managedObjectStore];
[placeMapping addAttributeMappingsFromDictionary:@{
@"place_id": @"place_id",
@"place_title": @"place_title",
@"site": @"site",
@"address": @"address",
@"phone": @"phone",
@"urating": @"urating",
@"worktime": @"worktime",
@"lat": @"lat",
@"lng": @"lng",
@"about": @"about",
@"discount": @"discount",
@"subcategory_title": @"subcategory_title",
@"subcategory_id": @"subcategory_id",
@"category_title": @"category_title",
@"image_url": @"image_url"}];
//RKEntityMapping *articleMapping = [RKEntityMapping mappingForEntityForName:@"Article" inManagedObjectStore:managedObjectStore];
//[articleMapping addAttributeMappingsFromArray:@[@"title", @"author", @"body"]];
//[articleMapping addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:@"categories" toKeyPath:@"categories" withMapping:categoryMapping]];
NSIndexSet *statusCodes = RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful); // Anything in 2xx
// here we need to change too
RKResponseDescriptor *responseDescriptor =
[RKResponseDescriptor responseDescriptorWithMapping:placeMapping
pathPattern:nil // @"/articles/:articleID"
keyPath:@"data.place_list"
statusCodes:statusCodes];
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://allocentral.api.v1.ladybirdapps.com/place/?access_token=19f2a8d8f31d0649ea19d478e96f9f89b&category_id=1&limit=10"]];
RKManagedObjectRequestOperation *operation = [[RKManagedObjectRequestOperation alloc] initWithRequest:request
responseDescriptors:@[responseDescriptor]];
operation.managedObjectContext = managedObjectStore.mainQueueManagedObjectContext;
operation.managedObjectCache = managedObjectStore.managedObjectCache;
[operation setCompletionBlockWithSuccess:^(RKObjectRequestOperation *operation, RKMappingResult *result) {
NSLog(@" successfull mapping ");
[self refreshContent];
} failure:^(RKObjectRequestOperation *operation, NSError *error) {
NSLog(@"Failed with error: %@", [error localizedDescription]);
}];
NSOperationQueue *operationQueue = [NSOperationQueue new];
[operationQueue addOperation:operation];
}
- (void) refreshContent {
// perform fetch
NSError *error = nil;
if (![self.fetchedResultsController performFetch:&error]) {
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
abort();
}
// reload data
[self.tableView reloadData];
}
it works perfect and gets all the objects and stores them in core data, BUT if some objects are deleted on the server, and they are not in the JSON response, they stay in the detebase. how can i make restkit clear out objects that are not in the response? thx
Upvotes: 1
Views: 1215
Reputation: 1031
Anytime you receive a new JSON response from your server, you should process it as normal, adding new entries into your Core Data objects.
Then iterate through your Core Data objects, and check to see if they're included in the JSON (using whatever method makes sense for your objects), and if not, delete them.
Alternatively, if you are passing some kind of ID in with the JSON, you could store each ID in an NSArray at the same time as you're adding objects to Core Data. Then do a predicate search for any Core Data objects that don't match the IDs in the array, and delete them.
Which is better depends on whether you have more new/existing items or more to-be-deleted items.
Upvotes: 1