尝试使用RestKit发出POST请求并将响应映射到Core Data [英] Trying to make a POST request with RestKit and map the response to Core Data

查看:155
本文介绍了尝试使用RestKit发出POST请求并将响应映射到Core Data的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



我不知道究竟要调用哪些方法来发出请求。我知道我应该使用 RKObjectManager 的方法,但我找不到合适的方法。



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

 'RKObjectManager'没有可见的@interface声明选择器'loadObjectsAtResourcePath:usingBlock:'


解决方案

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



<我假设您正在使用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:@/ whateverparameters:parameters];
RKObjectRequestOperation * operation = [objectManager objectRequestOperationWithRequest:请求成功:^(RKObjectRequestOperation * operation,RKMappingResult * result){
NSLog(@加载映射结果:%@,结果);
}失败:无;

如果您尝试定位核心数据,那么您将要使用 RKManagedObjectRequestOperation managedObjectRequestOperationWithRequest:success:failure:。 RestKit Github站点和头文档中的README.md中还有其他示例,单元测试中还有一公吨代码供参考。



< hr>

接下来,回应JRG-Developer的评论:



Ahem,这是一个非常可怕的答案原因多少。 (免责声明:我是RestKit的主要开发者)



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



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



接下来,您推荐的技术堆栈设置和使用更复杂,以便在您真正理解库后完成RestKit为您提供的相同内容。



让我们逐点看看:


  1. AFNetworking




    • AFN是一个出色的轻量级库,用于执行异步网络操作。如果您认为RestKit是一个包含许多实现客户端API的工具的工具箱,那么AFN就是锤子。

    • 我非常尊重AFN,在RestKit 0.20.x中,我们抛弃了老化的自制网络库,转而支持AFNetworking,因为它的设计优于已挂起的RestKit自定义网络堆栈自iOS 3.0以来。但是,仅AFN并不能为您提供足够的火力来完全实现与Core Data集成的API,而无需深入了解Core Data并自行实现大量同步代码。

    • RestKit的对象映射系统为您提供了一个高性能,一致的API,用于配置这些同步活动,而不是自己实现它们。这样可以实现一些严格的性能优化,我将在稍后返回。


  2. JSONKit




    • JSONKit是我高度重视的另一个图书馆,但它可能不值得你花时间。与 NSJSONSerialization 相比,JSONKit的JSON解析速度更高 - 但只有毫秒。

    • 作为为广泛部署的应用程序实现大型API客户端的人,我可以告诉您,您的时间不会用于JSON序列化/反序列化,而是用于处理您的JSON一旦被反序列化。


  3. MagicalRecord




    • MagicalRecord是一个核心数据便利库,为Core Data中的现有功能提供速记访问器。一旦你深入了解实现HTTP到核心数据同步方案真正需要的东西,它就不会改善你的生活。您的问题将与没有有关,Core Data获取请求的语法过于冗长,维护对托管对象上下文的引用或者获取Core Data堆栈设置不方便。


那么让我们谈谈真正的问题是什么实现一个iOS / OS X应用程序,暂时将API建模到Core Data中:


  1. 异步访问

    • 您将遇到的第一个问题是您习惯于以同步的,面向主线程的方式进行编程,但现在您需要启动加载的AFNetworking请求您的JSON,但随后将其加载到您的对象模型中。没问题,只需等待 AFJSONRequestOperation 回到成功区块并更新Core Data,对吧?错误。现在,您正在异步执行网络I / O,但随后执行在主线程上更新数据模型的 CPU密集型任务。现在你的应用程序性能糟透了,你不知道该怎么做。如何将同步移至后台?完成后如何通知用户界面?


  2. 错误处理

    • 遇到错误会怎样?当您收到网络错误时,您会怎么做?当网络操作完成但您在Core Data访问期间遇到错误时,您会怎么做?你打算如何处理它?您是否要将此错误处理代码放入所有控制器中?您打算如何封装所有逻辑?

    • 您将如何处理服务器返回的错误?


  3. 唯一对象标识

    • 好的,现在您已经加载了JSON,并希望将其放入Core Data 。大。你如何区分商店中的现有对象与需要创建的新对象?

    • 如果你弄错了,你现在有了重复的对象。

    • 如果你做对了,但是从主线程上下文中做到这一点,你的用户界面就会被屏蔽,你的表现很糟糕。

    • 如果你做对了,那就去做吧后台线程你可能会遇到并发问题。

    • 如果你做对了,但是用持有的获取请求点击持久存储来识别你的独特对象,你现在就遇到了性能问题。


  4. 删除孤立对象

    • 将数据集与服务器,你打算如何从服务器上不再存在的本地商店中删除死对象?


  5. 表现

    • 正如我在这个咆哮的早期部分中所提到的那样,所有道路最终都将导致性能提升即如果您实际上正在尝试构建可以大规模工作并使用户满意的内容,那么您将不得不应对严重的性能问题。 Giddy up。


还有许多额外的问题需要争辩一旦你的应用程序成功,包括可测试性,可维护性等等。你对这些事情有多少想法?



我想我的主要观点是(来自我的)从花生画廊那里听到关于如何解决基本工程问题的疯狂欢呼或嘲笑,这太常见了。现实情况是,基本复杂性问题的解决方案将具有相对于接近问题的学习曲线。



它是更远,更容易采取一个独立的功能,并确定一个令人满意的解决方案,而不是试图解决一个更大但更有趣的问题。



但这样做并不意味着你要通过捆绑一堆你已经听过的库提供一个问题子集的良好实现而不是更大的聚合问题方法来产生一个更强大的解决方案。



为什么没有人开源他们自己的AFN / JSONKit /核心数据/ MagicalRecord mashup,如果它们比RestKit好得多,可以将RestKit从水中吹出来?



我担心清醒的事实是:它就不那么容易了。



干杯!


I am using RestKit framework and i want to make a POST HTTP request. The response is JSON. I want to put the JSON response automatically in the CoreData.

I don't know exactly what methods to call to make the request. I know that I should use RKObjectManager's methods but I didn't find the right one.

I found this method postObject:delegate: but I don't what the object to pass as parameter. I also find this method in documentation: loadObjectsAtResourcePath:usingBlock: but I can't use it because it tells me:

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

解决方案

Vlad - First off, let's get an answer in place to your original question:

I assume that you are working off of RestKit 0.20.0, but are familiar with the RestKit 0.10.x API's and are consulting outdated information. The first place that you should be turning is to RKObjectManager.h -- the headers are always going to be up to date and will contain docs about what methods are available. Next, you can always view the latest documentation built from the source code on the latest API docs site.

What you want to do here is create an 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];

If you are trying to target Core Data, then you'll want to use RKManagedObjectRequestOperation and managedObjectRequestOperationWithRequest:success:failure:. There are additional examples available in the README.md on the RestKit Github site and in the header docs and there is a metric ton of code in the unit tests for reference as well.


Next, in response to the comments from JRG-Developer:

Ahem, this is a really terrible answer for a number of reasons. (Disclaimer: I am the principal developer of RestKit)

First of all, what version of RestKit are you using? If you are using a recent version (i.e. in the 0.20.x pre-release series) then the methods for loading collections of objects have been replaced with better names: getObjectsAtPath:. This is fully documented in both the API documentation (Making Requests by Path) and in the 0.10 to 0.20 migration guide.

I suspect that the original issue here stems from referring to outdated documentation along with recent code.

Next, the stack of technologies you are recommending is far more complicated to setup and use to accomplish the same things that RestKit provides for you once you actually understand the library.

Let's take a look at this point by point:

  1. AFNetworking

    • AFN is a great, lightweight library for performing asynchronous networking operations. If you think of RestKit as a toolbox containing a number of tools for implementing client side API's, then AFN is the hammer.
    • I have tremendous respect for AFN and in RestKit 0.20.x, we dumped our aging homebrewed networking library in favor of AFNetworking because its design was superior to the RestKit custom networking stack that has been hanging around since iOS 3.0. AFN alone, however, does not provide you with enough firepower to completely implement an API that integrates with Core Data without having deep knowledge of Core Data and implementing a large amount of synchronization code yourself.
    • RestKit's object mapping system gives you a performant, consistent API for configuring these synchronization activities rather than implementing them yourself. This enables some serious performance optimizations that I will return to later.
  2. JSONKit

    • JSONKit is another library that I hold in high regard, but it's probably not worth your time. When compared to NSJSONSerialization, the JSON parsing speed of JSONKit is superior -- but only by milliseconds.
    • As someone who has implemented large API clients for widely deployed apps, I can tell you that your time is not going to be spent in JSON serialization/deserialization, but in the code that processes your JSON once it has been deserialized.
  3. MagicalRecord

    • MagicalRecord is a Core Data convenience library that provides shorthand accessors for existing functionality in Core Data. It is not going to improve your life once you get into the nuts and bolts of what it really takes to implement an HTTP to Core Data synchronization scheme. Your problems will have nothing to do with the syntax of Core Data fetch requests being too verbose, it being inconvenient to maintain a reference to your managed object context, or with getting the Core Data stack setup.

So let's talk about what the real problems are with implementing an iOS / OS X application that models an API into Core Data for a moment:

  1. Asynchronous Access
    • The first problem you are going to run into is that you are used to programming in a synchronous, main thread oriented way, but now you need to fire off an AFNetworking request that loads your JSON, but then load it into your object model. No problem, just wait for the AFJSONRequestOperation to hit you back in the success block and update Core Data, right? Wrong. Now you are doing your network I/O asynchronously, but then doing the CPU Intensive task of updating your data model on the main thread. Now your app performance sucks and you don't know what to do about it. How do you move that synchronization into the background? How do you notify the UI once its done?
  2. Error Handling
    • What happens when you hit an error? What do you do when you get a network error? What do you do when the network operation completes, but you hit an error during Core Data access? How are you going to handle it? Are you going to put this error handling code into all of your controllers? How are you going to encapsulate all that logic?
    • How are you going to handle errors that are returned by your server?
  3. Unique Object Identification
    • Okay so now you've loaded your JSON and you want to put it into Core Data. Great. How are you going to differentiate existing objects within the store versus new ones that need to be created?
    • If you get this wrong, you now have duplicate objects.
    • If you get this right, but do it from a main thread context, your UI is blocked and your performance sucks.
    • If you get this right, but do it on a background thread you may have concurrency problems.
    • If you get this right, but hit the persistent store with fetch requests to identify your unique objects you now have a performance problems.
  4. Deleting Orphaned Objects
    • Once you synchronize your data set with the server, how are you going to take care of removing dead objects from the local store that no longer exist on the server?
  5. Performance
    • As I've alluded to in several earlier parts of this rant, all roads will eventually lead to performance. If you are actually trying to build something that will work and delight users on a large scale, you are going to have to contend with serious performance problems. Giddy up.

There are a number of additional problems you will have to contend with once your application is successful, including testability, maintainability, etc. How much are you thinking about these things?

I guess my main point here is that is (from my perspective) far too common to hear insane cheering or jeering coming from the peanut gallery about how to tackle fundamental engineering problems. The reality is that the solution to problems with essential complexity will have a learning curve that is relative to that of problem being approached.

It is far, far easier to take a discrete slice of functionality and nail down a satisfactory solution than it is to try and approach a larger, but more interesting problem.

But that does not mean that you are going to produce a more robust solution by lashing together a bunch of libraries that you have heard provide nice implementations of a subset of a problem than a larger approach to the aggregate problem.

Why hasn't anybody Open Sourced their own AFN/JSONKit/Core Data/MagicalRecord mashup and blow RestKit out of the water if they are so much better than RestKit?

I'm afraid that the sober truth is: it just ain't that easy.

Cheers!

这篇关于尝试使用RestKit发出POST请求并将响应映射到Core Data的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆