将JSON对象存储到Core Data中

时间:2021-09-13 17:08:12

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:

我正在尝试将本地核心数据数据库与远程JSON API同步。我正在使用RestKit将JSON值映射到本地托管对象。这是一段代码:

- (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

它工作得很完美并获取所有对象并将它们存储在核心数据中,但如果在服务器上删除了某些对象,并且它们不在JSON响应中,则它们会保留在执行库中。我怎样才能使restkit清除不在响应中的对象?谢谢

1 个解决方案

#1


1  

Anytime you receive a new JSON response from your server, you should process it as normal, adding new entries into your Core Data objects.

无论何时从服务器收到新的JSON响应,您都应该正常处理它,在Core Data对象中添加新条目。

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.

然后遍历您的Core Data对象,并检查它们是否包含在JSON中(使用对您的对象有意义的任何方法),如果没有,则删除它们。

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.

或者,如果您使用JSON传递某种ID,则可以在将对象添加到Core Data的同时将每个ID存储在NSArray中。然后执行谓词搜索任何与数组中的ID不匹配的Core Data对象,并删除它们。

Which is better depends on whether you have more new/existing items or more to-be-deleted items.

哪个更好取决于您是否有更多新/现有项目或更多待删除项目。

#1


1  

Anytime you receive a new JSON response from your server, you should process it as normal, adding new entries into your Core Data objects.

无论何时从服务器收到新的JSON响应,您都应该正常处理它,在Core Data对象中添加新条目。

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.

然后遍历您的Core Data对象,并检查它们是否包含在JSON中(使用对您的对象有意义的任何方法),如果没有,则删除它们。

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.

或者,如果您使用JSON传递某种ID,则可以在将对象添加到Core Data的同时将每个ID存储在NSArray中。然后执行谓词搜索任何与数组中的ID不匹配的Core Data对象,并删除它们。

Which is better depends on whether you have more new/existing items or more to-be-deleted items.

哪个更好取决于您是否有更多新/现有项目或更多待删除项目。