Answer the question
In order to leave comments, you need to log in
How to implement a callback to update the UI from an http request (NSURLSession)?
Hello!
I'm writing my first objective-c app for iOS 7.1. I, apparently, do not understand something fundamentally, so this question arose for me.
The application is quite simple: a client for interacting with an external service using some web api. I am using NSURLSession to send http requests.
My architecture is simple.
THETALETestViewController is a view controller. This class uses THETALEAPI.h
THETALEAPI is the web api implementation. I have separated it into a separate class so that each method of the external API is implemented in one place. Here is the formation of a request for each method. This class uses THETALEHttpHandler.h.
THETALEHttpHandler - This class is directly responsible for sending an http request and receiving an http response.
Here is the code from THETALEHttpHandler.m for sending a POST request.
-(void) sendPostToURL:(NSURL *)url withParams: (NSString *) inParams competion:(void (^) (NSData *data)) completion{
NSLog(@"sendPostToURL");
// _csrftoken некий токен в cookie
NSMutableDictionary *cookieProperties = [NSMutableDictionary dictionary];
[cookieProperties setObject:@"csrftoken" forKey:NSHTTPCookieName];
[cookieProperties setObject:_csrftoken forKey:NSHTTPCookieValue];
[cookieProperties setObject:;
NSURLSession *defaultSession = [NSURLSession sessionWithConfiguration:_sessionConfig];
NSMutableURLRequest * urlRequest = [NSMutableURLRequest requestWithURL:url];
// _csrftoken некий токен в параметр
NSString *params = [@[inParams, _csrftoken] componentsJoinedByString:@""];
[urlRequest setHTTPMethod:@"POST"];
[urlRequest setHTTPBody:[params dataUsingEncoding:NSUTF8StringEncoding]];
NSURLSessionDataTask * dataTask =[defaultSession dataTaskWithRequest:urlRequest
completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
NSLog(@"Got response %@ with error %@.\n", response, error);
if(error == nil)
{
NSString * text = [[NSString alloc] initWithData: data encoding: NSUTF8StringEncoding];
NSLog(@"Data = %@",text);
}
completion(data);
}];
[dataTask resume];
}
Answer the question
In order to leave comments, you need to log in
The completion block doesn't execute anywhere and doesn't go anywhere, it starts executing when the request has been completed one way or another. And the main thread should not wait for anyone. Just at the right time, the session will call the completion block, indeed, not in the main thread.
Some tips and diagram. Perhaps I will not offer an ideal option.
1. We cut everything before creating the session into a separate method, it is logical - we are preparing everything for further work.
2. We write a separate method that creates a task with which we will log in (what is in your method after creating the session). We create the task itself using the dataTaskWithRequest:completionHandler: method , the completion block will be called when the task is completed in one way or another. If success - to item 3
3. We call a separate method inside this block, where we will write further logic after the login, you can add the creation of other tasks there. It is better to call the method in the main thread, because probably want to do something with the UI.
[self performSelectorOnMainThread:@selector(afterLoginLogicMethod) withObject:nil waitUntilDone:NO];
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question