将 JSON 对象存储到核心数据中

Posted

技术标签:

【中文标题】将 JSON 对象存储到核心数据中【英文标题】:Storing JSON objects into Core Data 【发布时间】:2013-03-02 19:13:27 【问题描述】:

我正在尝试将我的本地核心数据数据库与远程 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];

它完美地工作并获取所有对象并将它们存储在核心数据中,但是如果某些对象在服务器上被删除,并且它们不在 JSON 响应中,它们会留在 detebase 中。我怎样才能让restkit清除不在响应中的对象?谢谢

【问题讨论】:

也许存储 JSON 字符串? 如何存储 JSON 帮助? 哦,我将尝试遍历核心数据中的现有对象,看看它们是否存在于 RKMappingResult *result 中!也许这会有所帮助 【参考方案1】:

每当您从服务器收到新的 JSON 响应时,您都应该照常处理它,将新条目添加到您的核心数据对象中。

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

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

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

【讨论】:

非常感谢,我去试试看。对不起,我不能评价,我没有足够的代表) @Paul 无论您的代表如何,您都应该能够将答案标记为已接受——当然,假设它是有帮助的。 ;) 祝你好运。

以上是关于将 JSON 对象存储到核心数据中的主要内容,如果未能解决你的问题,请参考以下文章

搜索核心数据与 Plist

将 json 对象存储到 postgresql 中的数据类型是啥?

如何将嵌套的 JSON 对象存储到 Firebase 数据库中?

使用 azure 数据工厂管道将 json 对象存储到 azure 表存储实体

核心数据:将对象从一个持久存储移动到另一个

在 MySQL 中存储相当大的 JSON 对象的最佳方法是啥