将核心数据与 Web 服务同步

Posted

技术标签:

【中文标题】将核心数据与 Web 服务同步【英文标题】:Synchronize Core Data with a Web Service 【发布时间】:2014-08-29 08:11:26 【问题描述】:

我有一个关于 CoreData 和 RESTful Web 服务的问题。 我读了这篇关于本地CoreData和远程数据同步的教程How To Synchronize Core Data with a Web Service – Part 1。 我无法理解,因为在方法中:

- (void)downloadDataForRegisteredObjects:(BOOL)useUpdatedAtDate

信息之前总是保存在 JSON 文件中

(使用方法:[self writeJSONResponse:responseObject toDiskForClassWithName:className];

当所有操作都完成后,就可以将它们存储在 CoreData 上。

这有什么潜在的动机吗?

为什么我们不能直接保存在 CoreData 上以删除从读/写文件中增加的开销? 谢谢

【问题讨论】:

【参考方案1】:

tl;dr 这个保存到磁盘可能是不必要的开销。

我无法评论作者的动机,但我怀疑这是因为该应用程序是作为教程构建的,因此保存到文件是将从 Parse.com 下载数据的部分和将 JSON 解析为 CoreData 的部分分开。

【讨论】:

【参考方案2】:

在将值应用到托管对象之前没有必要写出 JSON 文件(而且,如果你确实写出 JSON 文件,甚至写到缓存目录,你应该在完成后将它们删除)。

以下是如何将来自 Web 服务响应的 JSON 数据应用到 Core Data 托管对象。

本文使用 AFHTTPRequestOperation,因此我们将在此处使用它。请注意,我假设您有某种方法可以获取您正在应用 JSON 数据的托管对象。通常这将使用find-or-create 模式来完成。

AFHTTPRequestOperation *operation = [[SDAFParseAPIClient sharedClient] HTTPRequestOperationWithRequest:request success:^(AFHTTPRequestOperation *operation, id responseObject) 
        if (json != nil && [json respondsToSelector:@selector(objectForKey:)])
            // Set the JSON values on the managed object, assuming the managed object properties map directly to the JSON keys
            [managedObject setValuesForKeysWithDictionary:json];
        
     failure:^(AFHTTPRequestOperation *operation, NSError *error) 
        NSLog(@"Request for class %@ failed with error: %@", className, error);
    ];

我假设 SDAFParseAPIClient 已经解析了 JSON。我们检查以确保解析的 JSON 是 NSDictionary,然后使用 Key Value Coding 将其应用于托管对象。

使用NSURLConnection 做同样的事情很简单,而且可能是更好的学习体验。其他 Foundation 网络方法(NSURLSession 等)的工作方式大致相同:

[NSURLConnection sendAsynchronousRequest:request queue:queue completion:(NSURLResponse *response, NSData *data, NSError *error)]
    NSIndexSet          *acceptableStatusCodes  =  [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(200, 99)];

    if ([acceptableStatusCodes containsIndex:[(NSHTTPURLResponse *)response statusCode]])
        if ([data length] > 0)
            // Parse the JSON
            id json = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error];
            if (json != nil && [json respondsToSelector:@selector(objectForKey:)])
                // Set the JSON values on the managed object, assuming the managed object properties map directly to the JSON keys
                [managedObject setValuesForKeysWithDictionary:json];
             else 
                // handle the error
            
        
     else 
        // Handle the error
    
];

我们发送一个带有完成块的异步请求。该块通过NSHTTPURLResponseNSDataNSError 传递。首先,我们检查响应的statusCode 是否在 200 'OK' 范围内。如果不是,或者响应为 nil,我们可能已经收到了一个描述原因的 NSError。如果响应在 200 范围内,我们在将其交给NSJSONSerialization 之前确保 NSData 中有一些内容。解析 JSON 对象后,我们确保它响应相关的 NSDictionary 方法,然后使用键值编码将值应用于托管对象。这假定 JSON 键和值直接映射到托管对象的属性 - 如果它们不映射,则您有许多用于重新映射或转换键和值的选项,这些选项甚至超出了本问题的范围。

【讨论】:

以上是关于将核心数据与 Web 服务同步的主要内容,如果未能解决你的问题,请参考以下文章

如何在目标 c 中将核心数据对象同步到 Web 服务

IOS/Xcode:将 Web 服务提要保存到核心数据中

核心数据获取请求和未保存的更改

将 XMLRPC/Web 服务与核心数据集成

RestKit:如何删除核心数据条目以保持内容与服务器同步?

评估将核心数据与 Dropbox 同步的策略