一次多个 RKObjectManager (RestKit)
我正在测试 RestKit,需要访问不同的 BaseUrl,有时还“一次”从不同的地方访问具有相同 baseUrl 的 Web 服务,最后我还需要在同一控制器中使用不同的 ressourcePaths 访问相同的 baseUrl。
在我的应用程序委托中,我像这样设置了 RKObjectManager 单例。
RKObjectManager *objectManager = [RKObjectManager objectManagerWithBaseURL:kBaseUrl];
[objectManager registerClass:[EntityClass1 class] forElementNamed:@"element1"];
[objectManager registerClass:[EntityClass2 class] forElementNamed:@"element2"];
.
.
.
etc.
单例方法确实很容易使用,但是我不知道如何分离不同的 Web 服务调用。
在实现 RKObjectLoaderDelegate 的 MyViewController 中,我将有两种方法:
- (void)objectLoader:(RKObjectLoader *)objectLoader didLoadObjects:(NSArray *)objects {
//stuff with result
}
- (void)objectLoader:(RKObjectLoader *)objectLoader didFailWithError:(NSError *)error {
//stuff with error
}
当 MyViewController 使用一个 RKObjectManager 单例通过一个 baseUrl 访问一个 ressourcePath 时,这不会产生任何问题。
如果我以这种方式启动不同的请求:
[[RKObjectManager sharedManager] loadObjectsAtResourcePath:FLICKRPath delegate:self]
[[RKObjectManager sharedManager] loadObjectsAtResourcePath:FOURSQUAREPath delegate:self]
等等,在同一个MyController中,我的问题是FLICKRPath和FOURSQUAREPath当然有不同的baseUrl,但RKObjectManager只有一个?
如果我得到这个工作并且可以有不同的 RKObjectManagers 另一个问题就会出现。 委托方法 didLoadObjects 和 didFailWithError 将从两个 RKObjectManager 接收结果,除了它们的 baseUrl 之外,我看不到任何其他方法来区分它们。在委托方法中将每个返回值与 baseUrl 甚至更糟糕的 ressourcePath 进行比较对我来说根本没有吸引力。
如果我有不同的 RKObjectManager,我想我可以向它们传递不同的委托并构建专用于处理来自不同 baseUrl 和 ressourcePath 的返回值的类。这意味着我必须在 MyController 和 RestKit 之上构建另一个抽象,这看起来也很混乱。
我有一种强烈的感觉,我正在以错误的方式处理这个问题,RestKit 源代码非常令人印象深刻,这表明我正在与框架作斗争。我真的很感激有关该主题的一些最佳实践见解。我已经浏览了我能找到的所有资源和示例,但还没有看到上述用例。它始终是 1 个 RKObjectManager、1 个 baseUrl 和 1 个 ressourcePath。
先感谢您。
I am testing out RestKit and need to access different BaseUrls and also sometimes access a web service with the same baseUrl from different places "at once", lastly I also need to access the same baseUrl with different ressourcePaths in the same controller.
In my app delegate I set up the RKObjectManager singleton like this.
RKObjectManager *objectManager = [RKObjectManager objectManagerWithBaseURL:kBaseUrl];
[objectManager registerClass:[EntityClass1 class] forElementNamed:@"element1"];
[objectManager registerClass:[EntityClass2 class] forElementNamed:@"element2"];
.
.
.
etc.
The singleton approach is really easy to work with, I however can't figure out how to separate the different web service calls.
In MyViewController, which implement the RKObjectLoaderDelegate, I will have the two methods:
- (void)objectLoader:(RKObjectLoader *)objectLoader didLoadObjects:(NSArray *)objects {
//stuff with result
}
- (void)objectLoader:(RKObjectLoader *)objectLoader didFailWithError:(NSError *)error {
//stuff with error
}
This causes no problems when MyViewController uses one RKObjectManager singleton to access one ressourcePath with one baseUrl.
If I start different requests in this way:
[[RKObjectManager sharedManager] loadObjectsAtResourcePath:FLICKRPath delegate:self]
[[RKObjectManager sharedManager] loadObjectsAtResourcePath:FOURSQUAREPath delegate:self]
and so on, within the same MyController, my problem is that FLICKRPath and FOURSQUAREPath of course has different baseUrl, but the RKObjectManager only has one?
If I get this working and can have different RKObjectManagers another problem arises.
The delegate methods didLoadObjects and didFailWithError will receive results from both RKObjectManagers and I can't see any other way to tell them apart than from their baseUrls. Potentially comparing each return value with a baseUrl and, even worse, a ressourcePath, in the delegate method does not appeal to me at all.
If I have different RKObjectManagers I guess I could pass them different delegates and build classes dedicated to deal with the return values from different baseUrls and ressourcePaths. This would mean I had to build yet another abstraction on top of MyController and RestKit, which also seems messy.
I have a strong feeling I am going about this in the wrong way, the RestKit source is very impressive which indicates that is me fighting the framework. I would really appreciate some best practice insights on the subject. I have been through all the resources and examples that I could find but have not seen the above use case. It is always one RKObjectManager, one baseUrl and one ressourcePath.
Thank you in advance.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
由于还没有公认的答案:使用
RestKit
使用多个对象管理器非常简单。来自 Wiki (使用多个基本 URL(和多个对象管理器):
Since there is no accepted answer yet: using multiple object managers is quite simple using
RestKit
.From the Wiki (Using Multiple Base URLs (and Multiple Object Managers):
API 更改:
不在 RestKit v.0.10.3 中编译(loadObjectsAtResourcePath:delegate: 返回 void)。不过,该方法只包含几行代码,因此您仍然可以访问加载器,并添加 userData,其中包含以下内容:(
添加注释,以防其他新用户遇到与我相同的问题)。
API change:
doesn't compile in RestKit v.0.10.3 (loadObjectsAtResourcePath:delegate: returns void). That method just wraps a few lines of code, though, so you can still get at the loader, and add userData, with the following:
(adding note in case other new users run into the same issues I did).
顺便说一句,由于 RKRequest 上也提供了 userData 属性,因此您可以使用相同的方法来加载/识别请求。
例如一些post请求:
And by the way, since userData property is also available on RKRequest, you can use the same approach for loading/identifying requests.
For example, some post request:
使用objectLoader怎么样?
您将找到映射的对象类型/类
objectLoader.objectMapping.objectClass
并根据它而不是 url 添加您的条件希望它会有所帮助
How about using objectLoader.
You'll find the mapped object type/Class
objectLoader.objectMapping.objectClass
and add your conditions based on it instead of the urlHope it will help
可能的方法是为每个基本 URL 引入一个单例。
您可以根据需要实例化任意数量的 RKObjectManager 对象。但是,只有第一个会被共享。查看
initWithHTTPClient:
来源< /a>.我们不能使用默认的
sharedManager
方法来定位特定的对象管理器,但我们可以轻松实现我们自己的单例。以下是 Google 地图对象管理器的示例:用法:
Possible approach is to introduce one singletone for each base url.
You can instantiate as many
RKObjectManager
objects as you want. However, only the first one will become shared. Look intoinitWithHTTPClient:
sources.We can't use default
sharedManager
method to target specific object manager but we can easily implement our own singleton. Here's an example for Google Maps object manager:Usage: