Доступные через Интернет API предоставляют множество ресурсов для расширения функциональности ваших приложений iPhone. Эти API, как правило, используются в двух основных форматах данных: XML и JSON. IPhone SDK имеет встроенную поддержку синтаксического анализа XML, и об этом будет рассказано в отдельном руководстве. В этом руководстве мы сосредоточимся на добавлении поддержки JSON в ваши приложения iOS, демонстрируя, как создать клиентское приложение для чтения в Twitter.
Вступление
JSON Framework — чрезвычайно популярный фреймворк. Он используется для питания большой части часто используемых приложений в App Store, включая приложение Facebook, приложение Google Maps и практически всех клиентов Twitter.
Почему JSON?
Есть несколько причин выбрать JSON вместо XML. Основная причина, по которой JSON предпочтительнее, заключается в том, что файлы JSON обычно имеют меньший размер, чем их XML-аналоги, и это, естественно, приводит к меньшему времени загрузки. Еще одна причина, о которой стоит подумать, это то, что система push-уведомлений Apple лучше всего работает с полезными нагрузками JSON.
1. Начало работы
Создание проекта XCode
- Создайте новый проект Xcode по вашему выбору. Я собираюсь использовать шаблон View-Based.
- Загрузите JSON Framework здесь .
Добавление фреймворка
Добавить рамки просто. Вам просто нужно перетащить файлы в ваш проект. Существует возможность связать библиотеку с вашим проектом, но теперь эта опция устарела и не поддерживается.
- Перетащите папку JSON из DMG и поместите ее в свой проект Xcode. Вы можете добавить его в группу «Другие источники», если хотите.
- При появлении запроса выберите параметр «Копировать объекты в папку целевой группы».
- Добавлять:
#import "JSON.h"
в исходные файлы, где вы будете использовать рамки.
2. Использование библиотеки JSON
Образец сообщения JSON
Ниже приведен пример сообщения JSON, представляющего, как может выглядеть объект person:
{ "firstName": "Джон", "lastName": "Смит", «возраст»: 25, "адрес": { "streetAddress": "21 2nd Street", "город": "Нью-Йорк", "штат": "Нью-Йорк", "postalCode": "10021" }, "телефонный номер": [ {"type": "home", "number": "212 555-1234"}, {"type": "fax", "number": "646 555-4567"} ] }
Разбор строки JSON
Для разбора вышеизложенного мы сначала загружаем сообщение JSON в строку NSString:
NSString * jsonString = [[NSString alloc] initWithContentsOfFile: [[NSBundle mainBundle] pathForResource: @ "data" ofType: @ "json"] кодировка: NSUTF8StringEncoding error: & error];
Из примера сообщения JSON видно, что данные заключены в квадратные скобки (например, [] ) и фигурные скобки (например, {} ). Скобки — это массивы данных, а скобки — это словари данных. Как видите, мы можем вкладывать массивы словарей, а объекты словаря могут содержать массивы для нескольких значений.
В приведенном выше примере у нас есть словарь для контакта с ключами, такими как имя, фамилия и т. Д. Ключ адреса указывает на другой словарь, который содержит свои собственные пары ключ-значение. Ключ phoneNumber в словаре содержит массив словарей.
Для разбора массива мы используем:
NSArray * results = [jsonString JSONValue];
Для разбора словаря мы используем:
NSDictionary * dictionary = [jsonString JSONValue]; NSArray * keys = [словарь allKeys]; // ключи для вашего словаря
Выберите тот, который вам нужен, основываясь на вашем корневом объекте. Например, если ваш API возвращает список контактов, вы получите словарь массивов контактов. Точно так же, если вы запрашиваете временную шкалу в твиттере, вы получаете массив твитов, где каждый твит является словарем.
Создание строки JSON
Создание строки JSON очень просто и понятно. Вы создаете либо NSDictionary с соответствующими ключами и значениями, либо NSArray со списком объектов. Этот процесс довольно похож на то, как мы анализировали JSON на предыдущем шаге.
Вы бы создали словарь с вашими данными.
NSDictionary * contactData = [NSDictionary dictionaryWithObjectsAndKeys: _titleField.text, @ "title", _summaryField.text, @ "summary", _urlField.text, @ "url", _phoneField.text, @ "phone", _bdayField.text, @ "birthday", _addrField.text, @ "address", ноль];
Добавьте свой недавно созданный словарь данных в свой класс
NSDictionary * finalData = [NSDictionary dictionaryWithObject: contactData forKey: @ "contact"];
Затем сгенерируйте JSON-представление вашего словаря классов.
NSString * newJSON = [finalData JSONRepresentation];
Вы также можете создавать свои массивы и соответственно использовать словари или массивы.
Примечание. В инфраструктуре JSON нет метода, который бы проверял, является ли сообщение допустимым JSON.
3. Соединяем все вместе
Давайте создадим простое приложение для iPhone, которое показывает список последних 5 твитов, которые содержат мобтуты.
Мы собираемся использовать API поиска в Твиттере для простоты, поскольку он не требует аутентификации или авторизации.
Чирикать
URL для нашего запроса:
1
|
http://search.twitter.com/search.json?q=mobtuts&result_type=recent
|
Это вернет нам результат словаря, который содержит массив твитов.
Чтобы сделать жизнь немного проще, давайте сосредоточимся только на URL-адресе изображения профиля пользователя, тексте твита и имени пользователя в твиттере.
Один итоговый твит выглядит так:
{"profile_image_url": "http://a3.twimg.com/profile_images/949941117/zucker_normal.jpg", "creation_at": "чт, 10 июня 2010 г. 03:54:22 +0000", "from_user": "mariacarol" "," metadata ": {" result_type ":" недавний "}," to_user_id ": null," text ":" RT @mobtuts: как установить Android 2.2 Froyo на iPhone http://bit.ly/c8kBb6 ", "идентификатор": 15824617764, "from_user_id": 311442, "гео": нулевой, "iso_language_code": "ан", "источник": "Seesmic"}, { "profile_image_url": "http://a1.twimg.com /profile_images/655595496/retro9_normal.gif","created_at":"Thu, 10 июня 2010 г. 03:52:28 +0000 "," from_user ":" cead22 "," метаданные ": {" result_type ":" недавний "} , "to_user_id": null, "text": "Quiero un # iPhone4 con #FroYo - Как установить Android 2.2 Froyo на iPhone http://bit.ly/c8kBb6 (@mobtuts)", "id": 15824510273, "from_user_id": 34036310, "geo": null, "iso_language_code": "en", "source": "Twitter для BlackBerry \ u00ae"}, {"profile_image_url": "http://a1.twimg.com/profile_images /769690946/mobiletuts_icon_normal.png","created_at":"Thu, 10 июня 2010 г. 03:45:51 +0000 "," from_user ":" mobtuts ", "metadata": {"result_type": "недавний"}, "to_user_id": null, "text": "Подпишитесь на еженедельный подкаст @mobtuts сейчас! Выберите RSS http://bit.ly/9LMbGX или iTunes http://bit.ly/bq0QMC","id":15824135971,"from_user_id":104427899,"geo":null,"iso_language_code":"en ", "source": "HootSuite"}, {"profile_image_url": "http://a1.twimg.com/profile_images/63581538/tutsplus_normal.jpg", "creation_at": "Чт, 10 июня 2010 03:25:00 + 0000 "," from_user ":" tutsplus "," metadata ": {" result_type ":" недавний "}," to_user_id ": null," text ":" Подпишитесь на еженедельный подкаст @mobtuts сейчас! Выберите RSS http://bit.ly/9LMbGX или iTunes http://bit.ly/bq0QMC","id":15822900558,"from_user_id":2295627,"geo":null,"iso_language_code":"en ", "source": "TweetDeck"}, {"profile_image_url": "http://a1.twimg.com/profile_images/234225566/illustration_normal.jpg", "creation_at": "Чт, 10 июня 2010 03:22:33 + 0000 "," from_user ":" GreatTwitTips "," metadata ": {" result_type ":" недавний "}," to_user_id ": null," text ":" RT @mobtuts: RT @berryizm_feeds: 5 Советы разработчика тем BlackBerry от MMMOOO тема и приложение BlackBerry для разработчиков ... http://bit.ly/agf0ND","id":15822755393,"from_user_id":19637346,"geo":null,"iso_language_code":"en","source ":"Лента Твиттера"}
Мы видим, что мы ищем ключи «profile_image_url», «from_user» и «text» для нашего приложения.
Парсер
Давайте создадим простой JSON Parser и сделаем запрос из API.
Twitter_SearchAppDelegate.h
#import <UIKit / UIKit.h> @class Twitter_SearchViewController; @interface Twitter_SearchAppDelegate: NSObject <UIApplicationDelegate> { UIWindow * window; NSMutableData * responseData; Twitter_SearchViewController * viewController; } @property (nonatomic, retain) IBOutlet UIWindow * window; @property (nonatomic, retain) IBOutlet Twitter_SearchViewController * viewController; @конец
Теперь мы добавим каркас JSON в операторы импорта.
Twitter_SearchAppDelegate.m
#import "JSON.h"
Здесь мы изменим метод didFinishLaunchingWithOptions в делегате приложения и сделаем NSURLRequest для Twitter с URL-адресом, чтобы получить твиты, которые мы хотим обработать. Мы также установим делегат приложения в качестве делегата NSURLRequest.
- (BOOL) приложение: (UIApplication *) приложение didFinishLaunchingWithOptions: (NSDictionary *) launchOptions { // Точка переопределения для настройки после запуска приложения. // Добавить представление контроллера вида в окно и отобразить. responseData = [[NSMutableData data] сохранить]; твиты = [массив NSMutableArray]; NSURLRequest * request = [NSURLRequest requestWithURL: [NSURL URLWithString: @ "http://search.twitter.com/search.json?q=mobtuts&rpp=5"]]; [[NSURLConnection alloc] initWithRequest: запрос делегата: self]; вернуть ДА; }
Теперь, поскольку наш делегат приложения является делегатом NSURLRequest, мы должны реализовать эти методы делегата. Мы в первую очередь заинтересованы в получении уведомлений, когда данные отправляются нам и когда запрос завершен, и больше нет данных для получения.
#pragma mark NSURLConnection Делегированные методы - (недействительное) соединение: (NSURLConnection *) соединение didReceiveResponse: (NSURLResponse *) response { [responseData setLength: 0]; } - (недействительное) соединение: (NSURLConnection *) соединение didReceiveData: (NSData *) data { [responseData appendData: data]; } - (недействительное) соединение: (NSURLConnection *) соединение didFailWithError: (NSError *) error { label.text = [NSString stringWithFormat: @ "Ошибка подключения:% @", [описание ошибки]]; }
Это где наш парсер делает большую часть работы. Он анализирует файл JSON и создает массив твитов для нас. Мы получаем массив и передаем его в TableViewController для его отображения.
- (void) connectionDidFinishLoading: (NSURLConnection *) соединение {[освобождение соединения]; NSString * responseString = [[NSString alloc] initWithData: кодировка responseData: NSUTF8StringEncoding]; [responseData release]; NSDictionary * results = [responseString JSONValue]; NSArray * allTweets = [результаты objectForKey: @ "результаты"]; [viewController setTweets: allTweets]; [окно addSubview: viewController.view]; [window makeKeyAndVisible]; }
Простой TableView
Теперь мы просто используем массив, который мы создали из парсера, для отображения данных в нашем TableView.
Twitter_SearchViewController.h
#импорт@interface Twitter_SearchViewController: UITableViewController { NSArray * твиты; // это массив, который был передан нам от делегата приложения } @property (nonatomic, retain) NSArray * твиты; @конец
TweetsTableViewController.m
В контроллере нам сначала нужно синтезировать свойство, а затем установить количество строк, которые мы будем отображать
@ynthesize твиты; - (NSInteger) tableView: (UITableView *) tableView numberOfRowsInSection: (NSInteger) section { // Возвращаем количество строк в разделе. возврат [количество твитов]; }
Наконец, мы отобразим твиты, ссылаясь на их конкретные ключи из словаря. Из рассмотрения строки JSON ранее мы знаем, что ищем значения, связанные с ключами «from_user», «profile_image_url» и «text».
// Настройка внешнего вида ячеек табличного представления. - (UITableViewCell *) tableView: (UITableView *) tableView cellForRowAtIndexPath: (NSIndexPath *) indexPath { статическая NSString * CellIdentifier = @ "Cell"; UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier: CellIdentifier]; if (cell == nil) { cell = [[[UITableViewCell alloc] initWithStyle: UITableViewCellStyleSubtitle reuseIdentifier: CellIdentifier] autorelease]; } // Настраиваем ячейку ... NSDictionary * aTweet = [твиты objectAtIndex: [indexPath row]]; cell.textLabel.text = [aTweet objectForKey: @ "text"]; cell.textLabel.adjustsFontSizeToFitWidth = YES; cell.textLabel.font = [UIFont systemFontOfSize: 12]; cell.textLabel.numberOfLines = 4; cell.textLabel.lineBreakMode = UILineBreakModeWordWrap; cell.detailTextLabel.text = [aTweet objectForKey: @ "from_user"]; NSURL * url = [NSURL URLWithString: [aTweet objectForKey: @ "profile_image_url"]]; NSData * data = [NSData dataWithContentsOfURL: url]; cell.imageView.image = [UIImage imageWithData: data]; cell.selectionStyle = UITableViewCellSelectionStyleNone; возвратная ячейка; }
Дополнительные соображения
Если вы планируете использовать Three20 или httpriot , вам не нужно добавлять инфраструктуру JSON. Эти проекты уже включают его в свой код. Если вы планируете использовать ASIHTTPRequest , среда JSON не включена, и вам нужно добавить ее самостоятельно.