0

我正在编写一个使用 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];
}

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

提前谢谢了

4

2 回答 2

2

当您进行这样的异步调用时,绝对不要期望传统的返回设置。您的委托想法肯定会奏效,您也可以将数据作为 a@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];
于 2013-04-04T14:31:51.047 回答
1

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

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

NSURLRequest 也有一个字典,你可以使用它来设置任何类型的数据,一旦请求返回,你就需要处理它。这样,您可能会在相同的委托方法中处理所有请求,并根据请求属性确定要做什么。

URL 加载系统编程指南

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

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

于 2013-04-04T14:31:27.583 回答