Здравствуйте!
Пишу свое первое приложение на objective-c для iOS 7.1. Я, видимо, что-то принципиально не понимаю, поэтому у меня этот вопрос и возник.
Приложение довольно простое: клиент для взаимодействия с внешним сервисом по некому web api. Для отправки http-запросов я использую NSURLSession.
Архитектура у меня простая.
THETALETestViewController - это view controller. Данный класс использует THETALEAPI.h
THETALEAPI - это реализация web api. Я выделил в отдельный класс, чтобы каждый метод внешнего API был реализован в одном месте. Здесь происходит формирование запроса для каждого метода. Данный класс использует THETALEHttpHandler.h.
THETALEHttpHandler - этот класс отвечает непосредственно за отправку http-запроса и прием http-ответа.
Приведу код из THETALEHttpHandler.m для отправки POST - запроса.
-(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:[[NSDate date] dateByAddingTimeInterval:2629743] forKey:NSHTTPCookieExpires];
NSHTTPCookie *cookie = [NSHTTPCookie cookieWithProperties:cookieProperties];
[_httpCookieStorage setCookie:cookie];
[_sessionConfig setHTTPCookieStorage:_httpCookieStorage];
// пробовал и так
// // NSURLSession *defaultSession = [NSURLSession sessionWithConfiguration: defaultConfigObject delegate: nil //delegateQueue: [NSOperationQueue mainQueue]];
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];
}
Так вот, блок completion выполняется не в main thread, а асинхронно, поэтому пока отправляется запрос и идет прием и обработка ответа - main thread выполняется дальше. В принципе, это понятно и логично, но я хочу "логиниться" с помощью данного метода, соответственно, по нажатию на кнопку "Войти" у меня должен отправиться запрос и после успешного ответа и его обработки пользователь должен увидеть ответ. Какими возможностями iOS добиться такого поведения, чтобы main thread ждал завершения выполнения асинхронного блока и выводил соответствующую информацию? Или, может быть, ему не стоить ждать, а просто его как-то нужно оповестить?
Если, конечно, не выносить отдельные классы, а все делать в viewController, то, предполагаю, что подошли бы делегаты, но я хочу внести немного модульности в свое приложение.
Думаю, что данное требование достаточно банально и ответ где-то рядом, прошу объяснить, заранее спасибо!