ПРОГРАММИРОВАНИЕ ПОД IPHONE, IPAD OBJECTIVE-C часть 3

JSON

До сих пор мы работали с форматом представления данных XML. Это удобный формат, для которого написано множество парсеров. Но в последнее вермя все большей популярности набирает формат JSON. Большинство современных сервисов поддерживает оба формата (или только JSON). О том как работать с этим форматом представления данных и пойдет речь в уроке.

 

В первую очередь создадим новый проект на основе шаблона Single View Application и назовем его JSONExample. После чего добавим в него классы APIDownload и TouchJSON (TouchJSON · GitHub). С помощью первого мы будем скачивать данные с сети (если кто-то забыл как ним пользоваться — можна почитать в соответствующем уроке). Второй класс представляет из себя сам парсер, который преобразует формат данных JSON в объекты родных классов Objective-C (строки, словари и массивы). Так же, следует учесть важный момент, что эти классы не поддерживают ARC, следовательно, вам нужно добавить флаг компилятора -fno-objc-arc. О том как это сделать можете прочитать в уроке Automatic Reference Counting (ARC).

 

Лишь теперь мы можем перейти непосредственно к процесу программирования. Для начала я предлагаю вывести в консоль чистый, не распарсеный JSON. Это потребует от нас минимальных изменений кода. То есть, интерфейс класса ViewController пока что трогать вообще не будем, а его реализация выглядит так:

 

ViewController.m

<code data-result="[object Object]">#import "ViewController.h"
#import "APIDownload.h"

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];

    [APIDownload downloadWithURL:@"http://www.imaladec.net/phpExamples/news.php" 
                        delegate:self];
}

- (void)APIDownload:(APIDownload*)request {    
    NSString *result = [[NSString alloc] initWithData:request.downloadData
                                             encoding:NSUTF8StringEncoding]; 
    NSLog(@"%@", result);
}

@end</code>

 

В результате в консоль будет выведено много текста, этот же текст вы сможете увидеть при переходе по ссылке http://www.imaladec.net/phpExamples/news.php в обычном браузере.

 

Чтобы преобразовать полученые данные в массив изменим метод APIDownload:

 

<code data-result="[object Object]">- (void)APIDownload:(APIDownload*)request {    
    CJSONDeserializer *deserializer = [CJSONDeserializer deserializer];
    NSArray *response = [deserializer deserializeAsArray:request.downloadData 
                                                   error:nil];
    NSLog(@"%@", response);
}</code>

 

Теперь в консоли мы увидим не набор символов, а массив, в котором хранятся словари, а в словарях строки. Каждый такой словарь хранит в себе информацию о новости с сайта (заголовок, дату создания, ссылку и картинку). Всего сайт отдает десять последних новостей. То есть, фактически это то же самое, что мы делали в уроке Создаем свою читалку RSS, только в этот раз кода у нас гораздо меньше. Нам не нужно писать свой парсер и разбирать полученые данные по ключам. Всю работу за нас проделывает Touch JSON. Для чистоты эксперемента выведем полученые данные в таблицу. Первое, что для этого нужно сделать — добавить саму таблицу в наш проект. О том как это сделать можна почитать в уроке Добавляем таблицу на View. В результате наш код должен выглядить так:

 

ViewController.h

<code data-result="[object Object]">#import &lt;UIKit/UIKit.h&gt;

@interface ViewController : UIViewController 
&lt;UITableViewDelegate, UITableViewDataSource&gt;

@property (strong, nonatomic) IBOutlet UITableView *newsList;
@property (strong, nonatomic) NSArray *news;

@end</code>

 

ViewController.m

<code data-result="[object Object]">#import "ViewController.h"
#import "APIDownload.h"
#import "CJSONDeserializer.h"

@implementation ViewController

@synthesize newsList;
@synthesize news;

- (void)viewDidLoad
{
    [super viewDidLoad];

    [APIDownload downloadWithURL:@"http://www.imaladec.net/phpExamples/news.php" delegate:self];
}

- (void)viewDidUnload
{
    [super viewDidUnload];
    self.newsList = nil;
}

- (void)APIDownload:(APIDownload*)request {    
    CJSONDeserializer *deserializer = [CJSONDeserializer deserializer];
    self.news = [deserializer deserializeAsArray:request.downloadData 
                                                   error:nil];

    [newsList reloadData];
}

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return news.count;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle 
                                      reuseIdentifier:CellIdentifier];
    }

    NSDictionary *story = [news objectAtIndex:indexPath.row];
    cell.textLabel.text = [story objectForKey:@"name"];
    cell.detailTextLabel.text = [story objectForKey:@"storydate"];

    return cell;
}

@end</code>

 

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

Comments are closed.