6

我正在使用 RestKit 框架,我想发出一个 POST HTTP 请求。响应是 JSON。我想将 JSON 响应自动放入 CoreData。

我不确切知道要调用什么方法来发出请求。我知道我应该使用RKObjectManager's 方法,但我没有找到正确的方法。

我找到了这个方法postObject:delegate:,但我不知道要作为参数传递的对象。我也在文档中找到了这种方法:loadObjectsAtResourcePath:usingBlock:但我不能使用它,因为它告诉我:

No visible @interface for 'RKObjectManager' declares the selector 'loadObjectsAtResourcePath:usingBlock:'
4

1 回答 1

53

弗拉德 - 首先,让我们回答你原来的问题:

我假设您正在使用 RestKit 0.20.0,但熟悉 RestKit 0.10.x API 并且正在咨询过时的信息。您应该转向的第一个地方是RKObjectManager.h- 标头始终是最新的,并且将包含有关可用方法的文档。接下来,您始终可以在最新的 API 文档站点上查看由源代码构建的最新文档。

您在这里要做的是创建一个RKObjectRequestOperation

NSDictionary *dictionary = @{ @"firstParam": @(12345), @"secondParam": @"whatever"};
NSMutableURLRequest *request = [objectManager requestWithObject:nil method:RKRequestMethodPOST path:@"/whatever" parameters:parameters];
RKObjectRequestOperation *operation = [objectManager objectRequestOperationWithRequest:request success:^(RKObjectRequestOperation *operation, RKMappingResult *result) {
    NSLog(@"Loading mapping result: %@", result);
} failure:nil];

如果您尝试以 Core Data 为目标,那么您将需要使用RKManagedObjectRequestOperationand managedObjectRequestOperationWithRequest:success:failure:. RestKit Github 站点上的 README.md 和标头文档中提供了其他示例,单元测试中还有大量代码供参考。


接下来,针对 JRG-Developer 的评论:

嗯,出于多种原因,这是一个非常糟糕的答案。(免责声明:我是 RestKit 的主要开发者)

首先,您使用的是什么版本的 RestKit?如果您使用的是最新版本(即在 0.20.x 预发布系列中),则加载对象集合的方法已被替换为更好的名称:getObjectsAtPath:. 这在 API 文档(通过路径发出请求)和0.10 到 0.20 迁移指南中都有完整的记录。

我怀疑这里的原始问题源于引用过时的文档以及最近的代码。

接下来,一旦你真正理解了这个库,你推荐的技术栈的设置和使用来完成与 RestKit 为你提供的相同的事情要复杂得多

让我们逐点看一下:

  1. AF网络

    • AFN 是一个出色的轻量级库,用于执行异步网络操作。如果您将 RestKit 视为一个包含许多用于实现客户端 API 的工具的工具箱,那么 AFN 就是锤子。
    • 我非常尊重 AFN,在 RestKit 0.20.x 中,我们抛弃了陈旧的自制网络库,转而使用 AFNetworking,因为它的设计优于自 iOS 3.0 以来一直存在的 RestKit 自定义网络堆栈。然而,单独的 AFN 并不能为您提供足够的火力来完全实现与 Core Data 集成的 API,而无需深入了解 Core Data 并自己实现大量同步代码。
    • RestKit 的对象映射系统为您提供了一个高性能、一致的 API 来配置这些同步活动,而不是自己实现它们。这可以实现一些重要的性能优化,稍后我将返回。
  2. JSONKit

    • JSONKit 是我高度重视的另一个库,但它可能不值得你花时间。与 相比NSJSONSerialization,JSONKit 的 JSON 解析速度更胜一筹——但只有几毫秒。
    • 作为为广泛部署的应用程序实现大型 API 客户端的人,我可以告诉您,您的时间不会花在 JSON 序列化/反序列化上,而是花在处理 JSON 反序列化后的代码上。
  3. 神奇唱片

    • MagicalRecord 是一个 Core Data 便利库,它为 Core Data 中的现有功能提供速记访问器。一旦你深入了解实现 HTTP 到 Core Data 同步方案的具体细节,它不会改善你的生活。您的问题与 Core Data 获取请求的语法过于冗长、维护对托管对象上下文的引用或获取 Core Data 堆栈设置无关

因此,让我们暂时讨论一下实现将 API 建模为 Core Data 的 iOS / OS X 应用程序的真正问题是什么:

  1. 异步访问
    • 您将遇到的第一个问题是您习惯于以同步的、面向主线程的方式进行编程,但是现在您需要触发一个加载 JSON 的 AFNetworking 请求,然后将其加载到您的对象模型中。没问题,只需等待AFJSONRequestOperation成功块中的回击并更新核心数据,对吗?错误的。现在您正在异步执行网络 I/O,然后在主线程上执行更新数据模型的CPU 密集型任务。现在您的应用程序性能很差,您不知道该怎么办。您如何将该同步移至后台?完成后如何通知 UI?
  2. 错误处理
    • 当你遇到错误时会发生什么?遇到网络错误怎么办?网络操作完成,但访问 Core Data 时遇到错误怎么办?你打算怎么处理?你打算把这个错误处理代码放到你所有的控制器中吗?你将如何封装所有这些逻辑?
    • 您将如何处理服务器返回的错误?
  3. 唯一对象标识
    • 好的,现在您已经加载了 JSON,并且想要将其放入 Core Data 中。伟大的。您将如何区分商店中的现有对象与需要创建的新对象?
    • 如果你弄错了,你现在有重复的对象。
    • 如果你做对了,但是从主线程上下文中做,你的 UI 被阻塞并且你的性能很糟糕。
    • 如果你做对了,但在后台线程上做,你可能会遇到并发问题。
    • 如果你做对了,但使用 fetch 请求访问持久存储以识别你的唯一对象,那么你现在遇到了性能问题。
  4. 删除孤立对象
    • 将数据集与服务器同步后,您将如何处理从本地存储中删除服务器上不再存在的死对象?
  5. 表现
    • 正如我在这篇咆哮的前几部分中提到的那样,所有道路最终都会导致性能。如果您实际上是在尝试构建可以大规模使用并取悦用户的东西,那么您将不得不应对严重的性能问题。晕头转向。

一旦您的应用程序成功,您将不得不应对许多额外的问题,包括可测试性、可维护性等。您对这些事情的考虑程度如何?

我想我的主要观点是(从我的角度来看)太常见了,以至于无法听到来自花生画廊的疯狂欢呼或嘲笑如何解决基本工程问题。现实情况是,具有基本复杂性的问题的解决方案将具有与正在解决的问题相关的学习曲线。

与尝试解决更大但更有趣的问题相比,获取离散的功能部分并确定令人满意的解决方案要容易得多。

但这并不意味着您将通过将一堆库捆绑在一起来产生更强大的解决方案,您听说这些库提供了问题子集的良好实现,而不是解决聚合问题的更大方法。

为什么没有人开源他们自己的 AFN/JSONKit/Core Data/MagicalRecord mashup 并在 RestKit 比 RestKit 好得多的情况下将它们从水中淘汰?

恐怕清醒的事实是:这并不容易。

干杯!

于 2012-12-20T05:08:05.957 回答