Войти

Или войди с помощью

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

Разработка
Никита Narmo Дёнин avatar |

В связи с большой популярностью различных социальных сетей и микроблогов перед разработчиками приложений для 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, содержащий описание ошибки.

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

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

Примечание: для большей наглядности я постарался избежать autorelease-объектов там, где это возможно.

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

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, потому что парсер при разборе строки может возвращать также описание ошибки, если она возникнет.

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, и любая его часть может быть использована в любых целях без указания моего авторства.

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

13 комментариев

Котик
Котик
Котик
Котик
Котик
Котик
Котик
Котик
Котик
Котик
Котик
Котик
Котик из TikTok
Котик из TikTok
Котик из TikTok
Котик из TikTok
Момент из фильма
Момент из фильма
Момент из фильма
Момент из фильма
Момент из фильма
Момент из фильма
Момент из фильма
Момент из фильма
Момент из фильма
Момент из фильма
Момент из фильма
Момент из фильма
Момент из фильма
Момент из фильма
Момент из фильма
Момент из фильма
Момент из фильма
Момент из фильма
Мем стикер
Мем стикер
Мем стикер
Мем стикер
Мем стикер
Мем стикер
Мем стикер
Мем стикер
Мем стикер
Мем стикер
Мем стикер
Мем стикер
Мем стикер
Мем стикер
Мем стикер
Мем стикер
Мем стикер
Мем стикер
Мем стикер
Мем стикер
Мем стикер
Мем стикер
Мем стикер
Мем стикер
Мем стикер
Мем стикер
Мем стикер
Мем стикер
Мем стикер
Мем стикер
Мем стикер
Мем стикер
Мем стикер
Офис стикер
Офис стикер
Офис стикер
Офис стикер
Офис стикер
Офис стикер
Офис стикер
Офис стикер
Офис стикер
Офис стикер
Офис стикер
Офис стикер
Офис стикер
Офис стикер
Офис стикер
Офис стикер
Офис стикер
Видео мем
Видео мем
Видео мем
Видео мем
Видео мем
Видео мем

Какие правила в комментариях
  1. TauruS_iPhone4_now avatar
    TauruS_iPhone4_now 15 апреля 2011
    0

    Сам разработкой пока не занимаюсь, но появление подобных статей создает практически отдельный раздел сайта. Так держать! Думаю в будущем Никита сделает многое для айфонсру)

    iLokki avatar
    iLokki16 апреля 2011
    0

    @TauruS_iPhone4_now, +1
    Отличная статья, полностью поддерживаю идею отдельного раздела.
    Никита, спасибо!

    Войди на сайт, чтобы ответить
    Ответить
  2. Novikoff avatar
    Novikoff 15 апреля 2011
    0

    ув.разработчики загляните сюда http://www.iphones.ru/forum/index.php?showtopic=77833
    нужна помощь

    Войди на сайт, чтобы ответить
    Ответить
  3. Rusik avatar
    Rusik 16 апреля 2011
    0

    Никита, вижу ты уже бывалый разработчик.
    А под мак писать умеешь?
    у меня вот вопрос один
    http://*****
    Запрещено давать ссылки на сторонние ресурсы. Кроме того, есть раздел разработчиков на форуме.

    никто не отвечает пока
    может ты знаешь)

    Rusik avatar
    Rusik16 апреля 2011
    0

    @Rusik, пипец вы злые какие

    ну в жопу ваш форум
    он нифига неудобный

    Никита Narmo Дёнин avatar
    Никита Narmo Дёнин16 апреля 2011
    0

    @Rusik, Под Мак писать не умею.

    Afx40 avatar
    Afx4016 апреля 2011
    0

    @Rusik, а тут никакой Голубиной книги с тайными знаниями не надо, все по уставу и инструкции в три строчки.

    В windowDidLoad добавляем:

    // получаем root-control
    NSView* root = [[[self window] contentView] superview];
    // определяем его размер
    NSRect rc = [root bounds];
    // кнопку размером 10х10 помещаем в заголовок с коорд 30,0
    // а что бы было красиво, выясняйте размер заголовка
    rc.origin.x += 30; rc.size.width = 10;
    rc.origin.y = rc.size.height – 10; rc.size.height = 10;
    // создаем кнопку
    NSButton butt = [[NSButton alloc] initWithFrame:rc];
    // добавляем ее в root-control
    [root addSubview:butt];
    // обработку событий добавляем к кнопке с помощью
    // setTarget и setAction

    Afx40 avatar
    Afx4016 апреля 2011
    0

    Извиняюсь, это ответ Novikoff-у, а не Rusik

    Войди на сайт, чтобы ответить
    Ответить
  4. Rusik avatar
    Rusik 16 апреля 2011
    0

    Помогите мне тоже кто нибудь
    вот вопрос
    http://www.iphones.ru/forum/index.php?showtopic=77843

    Войди на сайт, чтобы ответить
    Ответить
  5. Afx40 avatar
    Afx40 16 апреля 2011
    0

    Вы лучше здесь сформулируйте вопрос, а то там по ссылке надо регистрироваться, и письмо с регистрацией не высылается. Но сам по себе вопрос “Как работает NSUndoManager” очень странный – в документации вообще-то все есть.

    Rusik avatar
    Rusik16 апреля 2011
    0

    @Afx40, эт блин
    я думал вопросы всем без регистрации показываются

    ну вот собственно вопрос (там подсветка синтаксиса, все как надо)
    http://pastie.org/1800936

    Модераторам:
    Только вот не надо эту ссылку стирать и говорить, что это ссылка на сторонний ресурс. Там текст только

    Afx40 avatar
    Afx4016 апреля 2011
    0

    @Rusik, можете уже начинать нервно смеяться – у Вас ВСЕ ПРАВИЛЬНО. Не найдя ошибки, я специально проверил – создал doc-based app, дословно перенес туда Ваш код. Все превосходно работает (Xcode 3.2.5). Могу высказать только одно предположение – пока Вы экспериментировали, что-то сломали в другом месте. Попробуйте создать проект заново.

    Afx40 avatar
    Afx4016 апреля 2011
    0

    P.S. Кстати, Вы там ничего не удаляли из сгенерированного текста, я надеюсь, а только добавляли свой текст?

    Войди на сайт, чтобы ответить
    Ответить

Нашли орфографическую ошибку в новости?

Выделите ее мышью и нажмите Ctrl+Enter.