Обсуждение

We use cookies. Read the Privacy and Cookie Policy

Обсуждение

Класс NSURLConnection можно использовать двумя способами — асинхронным и синхронным. При асинхронном соединении создается новый поток, и процесс загрузки выполняется в этом новом потоке. Синхронное соединение блокирует вызывающий поток, а содержимое загружается прямо в ходе обмена данными.

Многие разработчики полагают, что при синхронном соединении блокируется главный поток, но это неверно. Синхронное соединение всегда блокирует тот поток, в котором оно было инициировано. Если вы запускаете синхронное соединение из главного потока — да, главный поток будет заблокирован. Но синхронное соединение, запущенное из другого потока, будет напоминать асинхронное именно в том отношении, что оно никак не повлияет на главный поток. На самом деле единственное различие между синхронным и асинхронным соединениями заключается в том, что для асинхронного соединения среда времени исполнения создает отдельный поток, а для синхронного — нет.

Чтобы создать асинхронное соединение, необходимо следующее.

1. Иметь URL или экземпляр NSString.

2. Преобразовать строку в экземпляр NSURL.

3. Поместить URL в URL-запросе типа NSURLRequest, а если мы имеем дело с изменяемыми URL — в экземпляр NSMutableURLRequest.

4. Создать экземпляр NSURLConnection и передать ему URL-запрос.

Можно создать асинхронное соединение по URL с помощью метода класса sendAsynchronousRequest: queue: completionHandler:, относящегося к классу NSURLConnection. Этот метод имеет следующие параметры:

• sendAsynchronousRequest — запрос типа NSURLRequest, рассмотренный ранее;

• queue — операционная очередь. При желании можно просто выделить и инициализировать новую операционную очередь и передать ее этому методу;

• completionHandler — блоковый объект, выполняемый, когда асинхронное соединение завершает работу, успешно или неуспешно. Этот блоковый объект должен принимать три параметра:

• объект типа NSURLResponse, в котором заключается ответ, полученный нами от сервера, — при наличии такого ответа;

• данные типа NSData при их наличии. Это будут данные, собранные в ходе соединения по указанному URL;

• ошибка типа NSError в случае ее возникновения.

Метод sendAsynchronousRequest: queue: completionHandler: не вызывается в главном потоке. Поэтому, если вам потребуется решить задачу, связанную с пользовательским интерфейсом, убедитесь, что вернулись к главному потоку.

Итак, довольно теории, перейдем к примерам. В данном примере попытаемся собрать HTML-контент с домашней страницы Apple, а потом выведем эту информацию в строковом формате в окне консоли:

NSString *urlAsString = @"http://www.apple.com";

NSURL *url = [NSURL URLWithString: urlAsString];

NSURLRequest *urlRequest = [NSURLRequest requestWithURL: url];

NSOperationQueue *queue = [[NSOperationQueue alloc] init];

[NSURLConnection

sendAsynchronousRequest: urlRequest

queue: queue

completionHandler: ^(NSURLResponse *response,

NSData *data,

NSError *error) {

if ([data length] >0 &&

error == nil){

NSString *html = [[NSString alloc] initWithData: data

encoding: NSUTF8StringEncoding];

NSLog(@"HTML = %@", html);

}

else if ([data length] == 0 &&

error == nil){

NSLog(@"Nothing was downloaded.");

}

else if (error!= nil){

NSLog(@"Error happened = %@", error);

}

}];

Да, все так просто. Если вы хотите сохранить данные, которые мы загрузили на диск в ходе соединения, это можно сделать с помощью подходящих методов класса NSData, получаемых от завершающего блока:

NSString *urlAsString = @"http://www.apple.com";

NSURL *url = [NSURL URLWithString: urlAsString];

NSURLRequest *urlRequest = [NSURLRequest requestWithURL: url];

NSOperationQueue *queue = [[NSOperationQueue alloc] init];

[NSURLConnection

sendAsynchronousRequest: urlRequest

queue: queue

completionHandler: ^(NSURLResponse *response,

NSData *data,

NSError *error) {

if ([data length] >0 &&

error == nil){

/* Прикрепляем имя файла к каталогу с документами. */

NSURL *filePath =

[[self documentsFolderUrl]

URLByAppendingPathComponent:@"apple.html"];

[data writeToURL: filePath atomically: YES];

NSLog(@"Successfully saved the file to %@", filePath);

}

else if ([data length] == 0 &&

error == nil){

NSLog(@"Nothing was downloaded.");

}

else if (error!= nil){

NSLog(@"Error happened = %@", error);

}

}];

Все действительно просто. В более ранних версиях iOS SDK соединения по URL происходили с применением делегирования, но теперь модель стала обычной блоковой и вам не придется заниматься реализацией делегатов.

Данный текст является ознакомительным фрагментом.