创建一个类以从webservice上的Async调用返回数据

时间:2013-04-04 13:59:52

标签: iphone ios objective-c afnetworking

我正在编写一个使用Web服务获取一些JSON数据的应用程序,我需要通过不同的视图控制器从Web服务获取不同的数据。所以我想创建一个类来处理这个问题,目的是在将来发布它。

在我的课程中,我希望使用AFNetworking框架使用AFJSONRequestOperation从Web服务获取JSON数据,但这会异步返回数据,因此不像返回那样简单类方法的数据。

如何让我的类处理这些数据并将其传递回调用类?我是否必须像往常一样在传递数据时使用委托,还是有另一种方式?

+(NSDictionary*)fetchDataFromWebService:(NSString *)query{

NSURL *url = [NSURL URLWithString:query];

NSURLRequest *request = [NSURLRequest requestWithURL:url];

AFJSONRequestOperation *operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) {
    NSLog(@"Success");


} failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, id JSON) {
    NSLog(@"Fail");
}];

[operation start];

return ??? // I can't return anything here because AFJSONRequestOperation is completed Async
}

我应该这样做,并使用代理

+(void)fetchDataFromWebService:(NSString *)query{

NSURL *url = [NSURL URLWithString:query];

NSURLRequest *request = [NSURLRequest requestWithURL:url];

AFJSONRequestOperation *operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) {
    NSLog(@"Success");
    [self.delegate didFinishFetchingJSON:(NSDictionary*)json];        

} failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, id JSON) {
    NSLog(@"Fail");
    [self.delegate didFinishFetchingJSON:(NSDictionary*)json withError:(NSError*)error];
}];

[operation start];
}

使用异步调用创建此类类的最佳方法和最佳实践的任何帮助都将非常有用。

非常感谢提前

2 个答案:

答案 0 :(得分:2)

当你做这样的异步调用时,绝对不要指望传统的返回设置。您的委托理念肯定会有效,您也可以将数据作为@property或其他内容传递。但我首选的方法是:

 - (void)postText:(NSString *)text
   forUserName:(NSString *)username
 ADNDictionary:(NSDictionary *)dictionary
     withBlock:(void(^)(NSDictionary *response, NSError *error))block;

我用块作为参数声明方法。实现如下:

- (void)postText:(NSString *)text
     forUserName:(NSString *)username
   ADNDictionary:(NSDictionary *)dictionary
       withBlock:(void(^)(NSDictionary *response, NSError *error))block
{
    // Custom logic

    [[KSADNAPIClient sharedAPI] postPath:@"stream/0/posts"
                              parameters:params
                                 success:^(AFHTTPRequestOperation *operation, id responseObject)
     {
         if (block) {
             block(responseObject, nil);
         }
     }
                                 failure:^(AFHTTPRequestOperation *operation, NSError *error)
     {
         if (block) {
             block([NSDictionary dictionary], error);
         }
     }];
}

正如您所看到的,当我从Web服务获得响应时,我将对象传递回调用它的块。我将此方法称为:

[[KSADNAPIClient sharedAPI] postText:postText
                             forUserName:username
                           ADNDictionary:parameters
                               withBlock:^(NSDictionary *response, NSError *error)
    {
        if (error) {
          // Handle error
        } else {
          // Do other stuff
        }
    }];

因此,一旦你调用它,这个块在从服务获得响应之前不会做任何事情。然后在这个街区内如果你想要你可以打电话:

[self loadInfo:response];

答案 1 :(得分:1)

是的,您将使用委托方法。

我使用常规NSURLRequest和NSUrlConnection对象及其委托方法进行异步调用,并使用NSJSONSerialization将JSON解析为NSDictionary。不需要第三方图书馆。

NSURLRequest还有一个字典,您可以使用该字典设置在返回请求后处理请求所需的任何类型的数据。这样,您可以在相同的委托方法中处理所有请求,并根据请求属性确定要执行的操作。

URL Loading System Programming Guide

默认情况下,NSUrlConnection的initRequest方法甚至在主线程上运行委托方法,因此您不会遇到任何线程安全问题。但是,您也可以将startImmediately设置为NO,让它们在单独的主题上运行。

我并不反对使用第三方库,但这不是您需要它们的情况。