为 RestKit 框架编写 API 类

Posted

技术标签:

【中文标题】为 RestKit 框架编写 API 类【英文标题】:writing an API class for RestKit framework 【发布时间】:2013-01-09 08:49:48 【问题描述】:

我从 AFnetworking 切换到 RestKit。在 AFnetworking 中有一个 API 类。 API.h 类包含以下内容。

#import <UIKit/UIKit.h>
typedef void (^JSONResponseBlock)(NSDictionary* json);
@interface API : NSObject
//the authorized user
@property (strong, nonatomic) NSDictionary* user;

+(API*)sharedInstance;
//check whether there's an authorized user

//send an API command to the server
-(void)loginCommand:(NSMutableDictionary*)params onCompletion:(JSONResponseBlock)completionBlock;

我的 API.m 类看起来像这样。

+(API *)sharedInstance

    static API *sharedInstance = nil;
    static dispatch_once_t oncePredicate;
    dispatch_once(&oncePredicate, ^ 
        sharedInstance = [[self alloc]initWithBaseURL:[NSURL URLWithString:kAPIHost]];
    );
    return sharedInstance;


#pragma mark - init
//intialize the API class with the destination host name

-(API *)init

    //call super init
    self = [super init];

    if (self != nil)
        //initialize the object
        user = nil;

        [self registerHTTPOperationClass:[AFJSONRequestOperation class]];

        // Accept HTTP Header; see http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.1
        [self setDefaultHeader:@"Accept" value:@"application/json"];
    
    return self;


-(void)loginCommand:(NSMutableDictionary *)params onCompletion:(JSONResponseBlock)completionBlock
    NSLog(@"%@%@",kAPIHost,kAPILogin);
    NSMutableURLRequest *apiRequest = [self multipartFormRequestWithMethod:@"POST" path:kAPILogin parameters:params constructingBodyWithBlock:^(id <AFMultipartFormData>formData)
        //TODO: attach file if needed

    ];
    AFJSONRequestOperation *operation = [[AFJSONRequestOperation alloc] initWithRequest:apiRequest];
    [operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject)
        //success!
        NSLog(@"SUCCESSSS!");
        completionBlock(responseObject);
    failure:^(AFHTTPRequestOperation *operation, NSError *error)
        //Failure
        NSLog(@"FAILUREE!");
        completionBlock([NSDictionary dictionaryWithObject:[error localizedDescription] forKey:@"error"]);
    ];
    [operation start];


就像你看到的那样,我只实例化一次,然后把我所有的方法都放在这里。在我的视图控制器中,我只需要使用参数字典调用此方法。然后我可以读取整个 JSON 文件。

现在使用 restKit,我在 viewController 级别上完成了这一切。我想像 AFNetworking 那样拆分它。这就是我在 RestKit 中所做的,目前这一切都在 viewController 级别。

   //let AFNetworking manage the activity indicator
[AFNetworkActivityIndicatorManager sharedManager].enabled = YES;

// Initialize HTTPClient
NSURL *baseURL = [NSURL URLWithString:@"http://virtuele-receptie.preview.sanmax.be"];
AFHTTPClient* client = [[AFHTTPClient alloc] initWithBaseURL:baseURL];
//we want to work with JSON-Data
[client setDefaultHeader:@"Accept" value:RKMIMETypeJSON];

// Initialize RestKit
RKObjectManager *objectManager = [[RKObjectManager alloc] initWithHTTPClient:client];


//Do mapping

RKResponseDescriptor *responseDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:dataMapping
                                                                                   pathPattern:nil
                                                                                       keyPath:@"data"
                                                                                   statusCodes:[NSIndexSet indexSetWithIndex:200]];
[objectManager addResponseDescriptor:responseDescriptor];

NSDictionary *dict = [[NSDictionary alloc]initWithObjectsAndKeys:_txtLogin.text,@"email",_txtPass.text,@"pwd", nil];

[objectManager getObject:nil path:@"/nl/webservice/company-user/login/apikey/key12345678" parameters:dict
                 success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) 
                   //Success  
                 
                 failure:^(RKObjectRequestOperation *operation, NSError *error) 
                     //Failure
                 ];

【问题讨论】:

【参考方案1】:

到目前为止,对于 RestKit,我还没有看到对 API 类的巨大需求,就像您可能使用其他 HTTP 框架创建的那样。 RestKit 有自己的 HTTP 客户端(实际上只是 AFNetworking 的客户端),所以不需要为你的 HTTP 客户端设置一个类,而且我发现每次使用 RKObjectManager 时,我通常都希望访问方法参数并阻止回调在每个视图控制器中。换句话说,我不想在 API 类中运行 RestKit 网络代码,因为我基本上必须将整个调用包装在可以在视图控制器中访问的方法中(成功块、失败块等)。

从本质上讲,RestKit 的设计大大减轻了网络代码的负担,以我的经验——现在有 3 或 4 个应用程序——我还没有看到足够的理由编写像你描述的 API 类。

【讨论】:

以上是关于为 RestKit 框架编写 API 类的主要内容,如果未能解决你的问题,请参考以下文章

RestKit .20 RKRequestDescriptor postObject - (400-499) 中的预期状态代码,得到 200

错误:“沙箱与 Podfile.lock 不同步...”在使用 cocoapods 安装 RestKit 后

RestKit iOS 教程 - Xcode 无法识别 RestKit 类方法 - 缺少框架?

使用 RestKit 拉取 2 个 API

除了 Restkit,iOS 上的简单 Restful 框架/客户端?

使用 RESTKit 映射 iTunes 搜索 API 结果