问题
I am currently using AFNetworking in one of my iPhone app. It's really a handy library to make asynchronous calls. However, I ran into situations in my application where I need to get the data from the server to move forward. So I figured this way of waiting for the response back.
MyAFNetworkClient *httpClient = [MyAFNetworkClient sharedClient];
NSURLRequest *request = [httpClient requestWithMethod:@"GET" path:path parameters:nil];
__block int status = 0;
AFJSONRequestOperation *operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) {
[[NSNotificationCenter defaultCenter] postNotificationName:@"notificationName" object:JSON];
} failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, id JSON){
@throw error.userInfo;
status = 2;
NSLog(@"Error... Status Code 2");
}];
[httpClient enqueueHTTPRequestOperation:operation];
[httpClient.operationQueue waitUntilAllOperationsAreFinished];
while (status == 0)
{
// run runloop so that async dispatch can be handled on main thread AFTER the operation has
// been marked as finished (even though the call backs haven't finished yet).
[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode
beforeDate:[NSDate date]];
}
With this piece of code, I am able to wait for the response back from the server and able to proceed further. It really seemed to solve my problem, however, not sure if this is a good way to make the calls. If it is, is there a good design principle where I can keep the code common and use it across my application.
Thank you
回答1:
Never block the main (UI) thread. That is to say, never do networking synchronously.
The entire time your request loads, it will appear that your application has frozen—totally unresponsive to touch and system events until the request finishes.
At the very least, show a loading modal that doesn't dismiss until the request finishes. Even better, make it so a user can interact the app normally while the request is loading, if possible.
What you have here may technically work, but it's unacceptable for a real application.
回答2:
For all of them who are running into the same situation where you are making asynchronous calls and want to wait for the data to return back to the main thread to do other stuff, this might be of a little help
Scenario:
User authentication: User enters username, password and trying to log in.
Solution: Show them loading modal to tell them that is something is going on behind the scenes, once you get back the response, you can proceed to the main thread like below.
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 2 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
// perform next steps....
});
}
Thanks to @matt for the tip on what needs to be done in such cases.
来源:https://stackoverflow.com/questions/16577438/synchronous-afnetworking-calls