Я пишу свое первое приложение target-c для iOS 7.1. Я наверное чего-то принципиально не понимаю, почему у меня этот вопрос возник.
Приложение довольно простое: клиент для связи с внешним сервисом использует веб-API. Для отправки http-запросов я использую NSURLSession. У меня простая архитектура.
THETALETestViewController — это контроллер представления. Этот класс использует THETALEAPI.h THETALEAPI — это реализация веб-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 a token in 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];
// tried and so
// // NSURLSession *defaultSession = [NSURLSession sessionWithConfiguration: defaultConfigObject delegate: nil //delegateQueue: [NSOperationQueue mainQueue]];
NSURLSession *defaultSession = [NSURLSession sessionWithConfiguration:_sessionConfig];
NSMutableURLRequest * urlRequest = [NSMutableURLRequest requestWithURL:url];
// _csrftoken a token in the parameter
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];
}
Итак, завершение блока выполняется не в основном потоке, а асинхронно, поэтому пока идет запрос и идет прием и обработка ответа - основной поток работает. В принципе все понятно и логично, но я хочу "авторизоваться" с помощью этого метода, соответственно нажав на кнопку "Войти" я должен пройти после успешного запроса и обработки ответа и пользователь должен увидеть ответ. Какими возможностями iOS добиться такого поведения, чтобы основной поток ждал завершения асинхронного блока и отображал соответствующую информацию? А может, и не стоит его ждать, и его просто как-то надо оповестить?
Если, конечно, не делать отдельные классы, а делать все в viewController, то, допустим, подошли бы делегаты, но хочется сделать немного модульности в его применении.
Может я неправильно спроектировал систему, тогда можете пояснить или показать на примере, как это обычно делается?
Я думаю, что это требование довольно банально и ответ где-то рядом, поясните пожалуйста, заранее спасибо!