在iPhone应用中使用RestKit的最佳方法

49
我正在编写一款iPhone应用程序,最终决定使用RestKit作为连接REST服务的框架。
我的构建方式是使应用程序中的控制器完全不知道有RestKit的存在。例如,如果我有一个登录屏幕,在通常的RestKit场景中(基于示例程序以及RestKit开发人员创建的一些博客条目),您将实现RKRequestDelegate协议,并使用RKClient在控制器中调用服务,同时将self(控制器)作为委托传递。我希望将这个过程对开发控制器和视图的用户隐藏起来。
我的想法是这样的:我将拥有一个LoginService来登录用户。有一个名为LoginServiceDelegate的协议,其中包含了成功和失败的两种方法。控制器可以实现LoginServiceDelegate并调用LoginService中的login方法来获取成功或失败的回调。但是要做到这一点,我需要一种方式让LoginService将调用委托给控制器。RestKit不允许我这样做,而我能够这样做的唯一方式是用LoginServiceDelegate初始化LoginService,将该委托存储为属性,并在成功登录或失败时调用委托中的适当方法。
这种方式使我的控制器代码库最小化,并完全隐藏了LoginService的工作方式和内部使用的框架。使用委托还将控制器与模型解耦,因此我们有一个很好的MVC模式。但是我担心Model类保留Controller对象所产生的影响,因为它正在保存委托。
如果您想了解如何使用RestKit,那么以下代码片段应该能够为您提供更好的理解。如果您认为我的方法不错,那么您会怎样修改它以使其更好?如果您不喜欢我的方法,请告诉我您认为它不好的原因。
下面的代码片段应该能够帮助您更好地理解。
@protocol LoginServiceDelegate;

@interface LoginService : NSObject <RKRequestDelegate>{
    NSObject<LoginServiceDelegate> *_loginServiceDelegate;

}

@property (retain, nonatomic) NSObject <LoginServiceDelegate> *loginServiceDelegate;

- (id) initWithDelegate:(NSObject<LoginServiceDelegate>*) loginServiceDelegate;

- (void) login:(NSString *)username withPassword:(NSString *)password;

@end

@protocol LoginServiceDelegate
@optional

- (void) loginSuccess:(LoginInfo *) loginInfo;

- (void) loginFailure:(NSString *) message;

@end

干杯 !!!

1个回答

73

我是RestKit的作者,我们推崇使用这样的模式在RestKit之上构建更高级别的抽象。通常,我会围绕着一个模型对象来构建我的回调和其他功能,而不是创建一个新的LoginService类型的对象,但两种方式都可以。在我的示例中,你可以这样做:

@implementation RKUser
- (void)loginWithDelegate:(NSObject<RKUserAuthenticationDelegate>*)delegate {}
@end

@protocol RKUserAuthenticationDelegate
- (void)userDidLogin:(RKUser*)user;
- (void)userDidFailLoginWithError:(RKUser*)user;
- (void)userDidLogout:(RKUser*)user
@end

无论如何,我建议将您的委托从retain更改为assign。在dealloc方法中,您可以执行以下几个操作:

  1. 将delegate设置为nil,以避免在回调时崩溃
  2. 请求队列请求取消: [[RKRequestQueue sharedQueue] cancelRequestsWithDelegate:self];

这就是您需要从内存管理/维护的角度关注的全部内容。 我通常总是会为我的身份验证生命周期事件创建通知。

您正在正确的道路上,设计很好。

最好祝福, Blake


4
@blake-watters,感谢您提供这样一个出色的框架。很高兴知道我在正确的轨道上。 - Vidyanand
@blake-watters,我对您提供的代码有一个澄清。您提到loginWithDelegate将使用RKUserAuthenticationDelegate。但是假设在您的方法内部调用了post方法,并且您正在使用RKRequestDelegate并使用一些回调进行异步消息传递。那么您的回调将请求:didLoadResponse方法。如何传递您的RKUserAuthenticationDelegate。这就是我最初想做的事情。由于我无法找到将其发送到回调的方法,因此不得不将其作为LoginService对象的属性。 - Vidyanand
RKRequestDelegate在RK 0.2中已不再可用。 - gdm

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接