2013-08-31 40 views
5
-(void)getDataFromServer: (NSMutableDictionary *)dict 
{ 

NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"%@/doSomething",MainURL ]]; 
[AFJSONRequestOperation addAcceptableContentTypes:[NSSet setWithObject:@"text/html"]]; 

AFHTTPClient *httpClient = [[AFHTTPClient alloc] initWithBaseURL:url]; 
NSMutableURLRequest *request = [httpClient requestWithMethod:@"POST" path:nil parameters:dict]; 

AFJSONRequestOperation *operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request 
success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) 
{ 
    _myArray = JSON; 
    [_myTableView reloadData]; //Or do some other stuff that are related to the current `ViewController` 
} 
failure:^(NSURLRequest *request , NSURLResponse *response , NSError *error , id JSON) 
{ 
    NSLog(@"request: %@",request); 
    NSLog(@"Failed: %@",[error localizedDescription]); 
}]; 

[httpClient enqueueHTTPRequestOperation:operation]; 
} 

我在其中一个应用程序的7个不同的地方使用上面的代码。确切的代码块在我的ViewControllers中有7个重复。我通常用来做的是把我想用在NSObject类中的方法分配并在需要时使用它,但是因为上面是异步并且使用块,所以我不能只返回JSON到ViewController谁打电话给谁它和必须复制&粘贴在每一个ViewController上面的方法,我需要进去。将块传递给AFNetworking方法?

我的目标是在只有一个地方上面我的应用程序,并且仍然能够从不同ViewControllers把它在我的应用程序,获取我需要的数据。 我想避免使用NSNotificationKVO等观察者,并寻找更优雅的解决方案。 经过一番阅读后,我注意到可能会传递块。这是否是上述可能的解决方案?代码示例将不胜感激。

+1

除了下面的Gabriele的回答,您可能希望避免为每个请求启动一个新的AFHTTPClient。 –

+0

我正在为此编辑我的答案。谢谢你的提示。 –

回答

6

比化的API调用类似

+ (void)getDataFromServerWithParameters:(NSMutableDictionary *)params completion:(void (^)(id JSON))completion failure:(void (^)(NSError * error))failure { 
    NSString * path = @"resources/123"; 
    NSMutableURLRequest *request = [self.httpClient requestWithMethod:@"POST" path:path parameters:params]; 
    AFJSONRequestOperation *operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) { 
     if (completion) 
      completion(JSON); 
    } failure:^(NSURLRequest *request , NSURLResponse *response , NSError *error , id JSON) { 
     if (failure) 
      failure(error); 
    }]; 

    [httpClient enqueueHTTPRequestOperation:operation]; 
} 

你可以把这个方法的实用类像XYAPI,只是调用它从你的控制器一样

[XYAPI getDataFromServer:params completion:^(id JSON){ 
    // do something, for instance reload the table with a new data source 
    _myArray = JSON; 
    [_myTableView reloadData]; 
} failure:^(NSError * error) { 
    // do something 
}]; 

而且你不需要在每次请求时产生新的AFHTTPClient。在XYAPI类中配置和使用共享的一个。类似于

+ (AFHTTPClient *)httpClient { 
    static AFHTTPClient * client = nil; 
    static dispatch_once_t onceToken; 
    dispatch_once(&onceToken, ^{ 
     client = [[AFHTTPClient alloc] initWithBaseURL:[NSURL URLWithString:@"http://foo.com/api/v1/"]]; 
     [AFJSONRequestOperation addAcceptableContentTypes:[NSSet setWithObject:@"text/html"]]; 
    }); 
    return client; 
} 

请注意,此实现已在上面的示例中使用。
self在类方法的上下文中是类本身,所以self.httpClient确实在运行时解析为[XYAPI httpClient]

+0

很好的答案!非常详细,写得很好。我会测试它并报告回来。非常感谢。 – Segev