将块传递给AFNetworking方法?
-(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类中,并在需要时分配和使用它,但是由于上述方法是Async并使用块,因此我不能仅将JSON返回到ViewController
谁打电话给它,并且必须复制&将上述方法粘贴到我需要的每个ViewController
中.
I'm using the above code in 7 different places in one of my apps. The exact chunk of code is duplicated in 7 of my ViewControllers
. What I normally used to do is to put the method I want to use in a NSObject class and allocate and use it when ever I need but because the above is Async and using blocks I can't just return the JSON to the ViewController
who called it and have to copy & paste the above method in every ViewController
I need it in.
我的目标是将以上内容仅放在应用程序的一个位置,仍然可以从应用程序周围的不同ViewControllers
调用它,并获取所需的数据.
我想避免使用诸如NSNotification
或KVO
之类的观察器,而是寻找一种更优雅的解决方案.
经过一番阅读后,我注意到有可能绕过障碍物.以上是可行的解决方案吗?一个代码示例将不胜感激.
My goal is to have the above in only one place in my app and still be able to call it from different ViewControllers
around my app and get the data I need.
I'd like to avoid using an observer such as NSNotification
or KVO
and looking for a more elegant solution.
After some reading I noticed the possibility to pass blocks around. Is that a possible solution with the above? A code example would be appreciated.
将API调用的特征化为类似
Factorize the API call to something like
+ (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
之类的实用工具类中,并只需从您的控制器中调用它,例如
You can place this method in a utility class like XYAPI
and just invoke it from your controllers like
[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
类中配置并使用共享的.像
Also you don't need to spawn a new AFHTTPClient
at every request. Configure and use a shared one in the XYAPI
class. Something like
+ (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]
.
Note that this implementation is already used in the above example.self
in the context of a class method is the class itself, so self.httpClient
is indeed resolved at runtime as [XYAPI httpClient]
.