Objective-C 2.0, iPhone, iPod, iPad, iOS
Для того чтобы понять что описывается в этой статье, вам нужно иметь представление о том как создаются приложения для iOS. Если вы еще не понимаете основ Objective-C, то сначала посмотрите тему Разработка приложений для iOS. С чего начать (Xcode 4.2).
Теория
Для выполнения GET запросов в Objective-C можно использовать NSURLConnection.
Подробную информацию о NSURLConnection можно почитать в официальной документации https://developer.apple.com/library/mac ... rence.html
и
https://developer.apple.com/library/mac ... ction.html
NSURLConnection поддерживает синхронное и асинхронное выполнение запросов.
Для выполнения синхронных запросов используется sendSynchronousRequest:returningResponse:error:
Использование такого запроса не рекомендуется. Работа приложения остановится, пока данные не будут получены полностью, не произойдёт ошибка или истечет тайм-аут соединения. При использовании синхронного запроса есть и другие ограничения.
Для асинхронных запросов используется initWithRequest:delegate:
Код: Выделить всё
- (id)initWithRequest:(NSURLRequest *)request delegate:(id < NSURLConnectionDelegate >)delegate
- request
URL запрос
- delegate
Делегат получает сообщения в процессе загрузки данных.
В этой статье будет приведен пример использования асинхронного запроса.
Чтобы получить содержимое с URL адреса, необходимо реализовать следующие методы:
- connection:didReceiveResponse:
- connection:didReceiveData:
- connection:didFailWithError:
- connectionDidFinishLoading:
Создание приложения в Xcode 4.2 (без ARC)
1. Создаём новый проект
Называем его, например, MethodGET.
Добавляем Label, называем его label.
2. Пишем код
В ViewController.h объявляем переменную receivedData
Код: Выделить всё
#import <UIKit/UIKit.h> @interface ViewController : UIViewController { IBOutlet UILabel *label; NSMutableData *receivedData;} @end
Вы можете самостоятельно добавить кнопку и вызывать загрузку по нажатию на нее. В этом примере загрузка будет происходить при запуске приложения, поэтому пишем код в viewDidLoad.
Код: Выделить всё
- (void)viewDidLoad{ [super viewDidLoad]; // создаем запрос NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://flapps.ru/example/user-info.php"] cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:15.0]; // создаём соединение и начинаем загрузку NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self]; if (connection) { // соединение началось label.text = @"Connecting..."; // создаем NSMutableData, чтобы сохранить полученные данные receivedData = [[NSMutableData data] retain]; } else { // при попытке соединиться произошла ошибка label.text = @"Connection error!"; } }
- timeoutInterval - ожидание запроса в секундах
Подробнее о NSURLRequest можно прочитать в документации
https://developer.apple.com/library/mac ... rence.html
Для того чтобы передать параметры в запросе, достаточно написать их в url строке, например
Код: Выделить всё
"http://flapps.ru/example/user-info.php?param1=1¶m2=2"
Когда сервер подготовит ответ, делегат получит сообщение connection:didReceiveResponse:. По ответу можно будет определить объем получаемых данных, MIME тип, имя файла и другие META данные.
Сообщение connection:didReceiveResponse: может быть получено несколько раз за одно соединение. Это может произойти в случае если сервер произведет переадресацию или в случае получения нескольких частей одного файла большого объема.
При каждом получении сообщения connection:didReceiveResponse: нужно очистить все ранее полученные данные.
Код: Выделить всё
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response{ // получен ответ от сервера [receivedData setLength:0];}
Когда данные получаюся, посылается сообщение connection:didReceiveData:.
Данные могут быть получены не целиком, а по частям, поэтому все полученные данные надо объединять.
В этом методе можно сделать индикатор процесса загрузки файла.
Код: Выделить всё
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{ // добавляем новые данные к receivedData [receivedData appendData:data];}
Если во время загрузки произойдёт ошибка, то делегат получит сообщение connection:didFailWithError:.
Сведения об ошибки будут переданы в объекте NSError.
Данные об ошибки также можно получить из userInfo dictionary, по ключу NSURLErrorFailingURLStringErrorKey.
Подробнее о NSError можно прочитать здесь https://developer.apple.com/library/mac ... rence.html
Код: Выделить всё
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error { // освобождаем соединение и полученные данные [connection release]; [receivedData release]; // выводим сообщение об ошибке NSString *errorString = [[NSString alloc] initWithFormat:@"Connection failed! Error - %@ %@ %@", [error localizedDescription], [error description], [[error userInfo] objectForKey:NSURLErrorFailingURLStringErrorKey]]; label.text = errorString; [errorString release];}
Если соединение успешно завершено, то делигат получит сообщение connectionDidFinishLoading:.
Код: Выделить всё
- (void)connectionDidFinishLoading:(NSURLConnection *)connection { // данные получены // здесь можно произвести операции с данными // можно узнать размер загруженных данных //NSString *dataString = [[NSString alloc] initWithFormat:@"Received %d bytes of data",[receivedData length]]; // если ожидаемые полученные данные - это строка, то можно вывести её NSString *dataString = [[NSString alloc] initWithData:receivedData encoding:NSUTF8StringEncoding]; label.text = dataString; // освобождаем соединение и полученные данные [connection release]; [receivedData release]; [dataString release];}
Код полностью
Код: Выделить всё
- (void)viewDidLoad{ [super viewDidLoad]; // создаем запрос NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://flapps.ru/example/user-info.php"] cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:15.0]; // создаём соединение и начинаем загрузку NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self]; if (connection) { // соединение началось label.text = @"Connecting..."; // создаем NSMutableData, чтобы сохранить полученные данные receivedData = [[NSMutableData data] retain]; } else { // при попытке соединиться произошла ошибка label.text = @"Connection error!"; } } - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response{ // получен ответ от сервера [receivedData setLength:0];} - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{ // добавляем новые данные к receivedData [receivedData appendData:data];} - (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error { // освобождаем соединение и полученные данные [connection release]; [receivedData release]; // выводим сообщение об ошибке NSString *errorString = [[NSString alloc] initWithFormat:@"Connection failed! Error - %@ %@ %@", [error localizedDescription], [error description], [[error userInfo] objectForKey:NSURLErrorFailingURLStringErrorKey]]; label.text = errorString; [errorString release];} - (void)connectionDidFinishLoading:(NSURLConnection *)connection { // данные получены // здесь можно произвести операции с данными // можно узнать размер загруженных данных //NSString *dataString = [[NSString alloc] initWithFormat:@"Received %d bytes of data",[receivedData length]]; // если ожидаемые полученные данные - это строка, то можно вывести её NSString *dataString = [[NSString alloc] initWithData:receivedData encoding:NSUTF8StringEncoding]; label.text = dataString; // освобождаем соединение и полученные данные [connection release]; [receivedData release]; [dataString release];}
3. Можно протестировать приложение
Можно запустить приложение в симуляторе или на своем устройстве.
О том как запустить приложение на своём устройстве без сертификата разработчика можно прочитать в теме Запуск приложения на iPhone без сертификата (Xcode 4.2).
Скрипт который я открывал в приложении показывает UserAgent.
При запуске приложения, я увидел html код загруженной страницы.
Код: Выделить всё
HTTP_USER_AGENT: MethodGET/1.0 CFNetwork/548.0.3 Darwin/11.2.0<br />