Разработка Показываем таймлайн Twitter

В связи с большой популярностью различных социальных сетей и микроблогов перед разработчиками приложений для iPhone часто возникает задача интеграции с ними. В этой статье будет показано, как простыми средствами встроить в приложение ленту последних записей из Твиттера.

Задача получения ленты записей из Твиттера делится на загрузку данных с сервера, их обработку и отображение. В качестве источника записей использовался формат JSON. Я продемонстрирую работу с JSON на примере одной из существующих библиотек, а также способы получения данных с удалённых серверов с помощью синхронных и асинхронных запросов.

Существует несколько свободных библиотек для работы с JSON на устройствах под управлением iOS. Из самых известных стоит отметить JSON Framework (именно эта библиотека была использована мной в процессе написания статьи) и TouchJSON. Эти библиотеки готовы для использования в проектах для iOS. Можно также воспользоваться другими библиотеками (например, легковесной cJSON), написав для них «обёртки» на Objective-C (такие обёртки по-английски называются wrapper).

Для получения последних записей из Твиттера не обязательно регистрировать своё приложение и получать ключ разработчика. У Твиттера есть открытый API, позволяющий получить ленту в виде объектов JSON. Для её получения надо всего лишь обратиться по адресу следующего вида:

http://twitter.com/statuses/user_timeline/USERNAME.json

где USERNAME — это имя пользователя, зарегистрированного в Твиттере. В случае, если такого пользователя не существует, придёт ответ в виде JSON, содержащий описание ошибки.

Синхронная загрузка данных

При использовании синхронных запросов мы отправляем запрос на сервер и ждём, пока от него придёт ответ. При этом выполнение потока, из которого была осуществлена отправка запроса, приостанавливается до прихода ответа. После того, как сервер ответил, и мы получили необходимые для работы данные, выполнение потока продолжается.

Синхронный запрос для получения ленты пользователя Твиттера отправляется следующим образом:

NSString *tweetsUrlString = [[NSString alloc] initWithFormat:@»http://twitter.com/statuses/user_timeline/%@.json», USERNAME]; NSURL *url = [[NSURL alloc] initWithString:tweetsUrlString]; [tweetsUrlString release]; NSURLRequest *request = [[NSURLRequest alloc] initWithURL:url]; [url release]; NSURLResponse *response = nil; NSError *error = nil; NSData *responseData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];

В результате выполнения этого метода в объект responseData запишется ответ от сервера. Объекты response (экземпляр NSURLResponse) и error (экземпляр NSError) будут содержать соответственно данные ответа (например, кодировку возвращаемых данных или тип MIME) и ошибку, если таковая возникла в процессе выполнения запроса.

После получения необходимых данных в виде объекта NSData можно отправить их на разбор в парсер JSON. Как уже было сказано в начале статьи, я воспользовался библиотекой JSON Framework. Данные, полученные от сервера, были преобразованы в NSString, потому что парсер при разборе строки может возвращать также описание ошибки, если она возникнет.

Читайте также  Apple отучит подбирать чужой iPhone

NSString *responseString = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding]; SBJsonParser *parser = [[SBJsonParser alloc] init]; NSError *jsonError; tweets = [[parser objectWithString:responseString error:&jsonError] retain]; [responseString release];

В результате выполнения этого кода в объекте tweets будет находиться массив из словарей (экземпляров NSDictionary), каждый из которых представляет одну запись в Twitter со всеми сопутствующими параметрами (такими, как текст твита, дата публикации, данные геолокации и т.п.). Этот массив можно обработать и вывести на экран. В демо-проекте к этой статье лента записей выводится в виде таблицы.

Асинхронная загрузка данных

Такой способ загрузки является более предпочтительным, так как процесс получения данных от удалённого сервера происходит в отдельном потоке и даёт больше возможностей для контроля за этим процессом. Создание соединения для асинхронного запроса происходит так:

NSString *tweetsUrlString = [[NSString alloc] initWithFormat:@»http://twitter.com/statuses/user_timeline/%@.json», USERNAME]; NSURL *url = [[NSURL alloc] initWithString:tweetsUrlString]; [tweetsUrlString release]; NSURLRequest *request = [[NSURLRequest alloc] initWithURL:url]; [url release]; mConnection = [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:YES];

Параметр startImmediately:YES сообщает соединению, что загрузку можно начинать немедленно. Если передать в него значение NO, то отправку запроса придётся делать вручную:

mConnection = [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:NO]; [mConnection start];

Объект-делегат, переданный в параметре delegate, содержит следующие методы, которые будут вызываться в процессе работы соединения.

— (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error

Этот метод вызовется в том случае, если соединение прервалось в результате возникновения ошибки. Из него можно вызвать тот объект, который ожидает получения данных, и, например, показать сообщение об ошибке на экране.

— (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response

Этот метод вызывается после установления соединения. Из объекта response можно получить различные данные об ответе от сервера. Например, значение свойства expectedContentLength можно использовать для отрисовки прогресса загрузки.

— (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data

Асинхронные запросы получают данные порциями, и при получении очередной порции будет вызываться этот метод. Поэтому перед запуском запроса необходимо создать экземпляр объекта NSMutableData, в который и будут дописываться полученные порции данных.

— (void)connectionDidFinishLoading:(NSURLConnection *)connection

Этот метод вызывается по завершении загрузки данных. Здесь можно обработать полученные данные, освободить ненужные объекты и передать управление объекту, который ожидает эти самые данные (в нашем случае это таблица, куда выводятся твиты).

В демонстрационном проекте к этой статье на экран выводятся твиты из ленты Артура Малосиева:

В проекте используется макрос TRACE для переопределения NSLog. Сделано это с целью отключения вывода отладочной информации при сборке цели Release. Макрос выглядит так:

Читайте также  Стив Джобс здоров и полон сил

#ifdef DEBUG #define TRACE(a, …) NSLog(a, ##__VA_ARGS__) #else #define TRACE(a, …) #endif

Для того, чтобы этот макрос заработал, и вывод NSLog отключался при сборке цели Release, необходимо в настройках проекта сделать следующее.
— переходим на вкладку Build
— в выпадающем списке Configuration выбираем Debug
— в строке поиска вводим текст cflags
— в пункте Other C Flags вводим следующий параметр: -DDEBUG

Этот параметр сообщит компилятору, что при сборке цели Debug будет определена переменная DEBUG, и все вхождения TRACE будут заменены на NSLog. При сборке цели Release все вхождения TRACE будут отброшены, и вывод отладочной информации производиться не будет.

Исходные коды библиотеки JSON Framework распространяются на условиях лицензии BSD и доступны на github.

Скачать исходные коды демонстрационного проекта к статье можно также скачать с github. Проект распространяется на условиях Public Domain, и любая его часть может быть использована в любых целях без указания моего авторства.

Источник: iphones.ru

TRAVEL