我正在编写一个使用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];
}
使用异步调用创建此类类的最佳方法和最佳实践的任何帮助都将非常有用。
非常感谢提前
答案 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
,让它们在单独的主题上运行。
我并不反对使用第三方库,但这不是您需要它们的情况。