iOS-приложения зачастую используют XML либо JSON для получения данных от веб-сервисов. Лично, для меня парсинг XML — процедура не очень приятная. Парсинг JSON немного приятнее, но тут приходится прибегать к использованию сторонних компонент. Далее мы рассмотрим еще один вариант.

Вступление

Как мы знаем, в iOS и MacOS X широко используются Property list файлы. Foundation позволяет «сохранять» экземпляры классов в этот формат. «Сохраняются»  классы которые реализуют NSCoding-протокол. Некоторые из них это:

  • NSString
  • NSNumber
  • NSDate
  • NSData
  • NSArray
  • NSDictionary

А так же унаследованные от них. К тому же, никто не запрещает реализовать NSCoding в своих классах для последующей сериализации. Для чтения/записи файлов формата Property list не требуется никаких сторонних компонент, все уже есть в Foundation.

Ах, да. О чем это я? Я о альтернативе XML и JSON. Так вот, если веб-сервис умеет «отдавать» данные в формате Property list то парсинг и сохранение становится намного легче.

Примеры

Чтобы сохранить, к примеру, NSArray в plist (Property list) можно сделать вот так:

NSArray* array = ...;

[array writeToFile: @"file.plist" atomically:YES];

Как видим первый аргумент — это имя файла, второй определяет, записывать ли сразу в конечный файл либо записать в временный и скопировать на место нужного. Метод возвращает BOOL в зависмости от того успешно прошла запись или нет.

Чтобы «распарсить» plist есть несколько вариантов, в зависимости от ситуации. Если вам нужно открыть локальный файл, то:

+ (id)arrayWithContentsOfFile:(NSString *)aPath

Если получить какие-либо данные с веб-сервиса по URL то делаем так:

+ (id)arrayWithContentsOfURL:(NSURL *)aURL

К примеру, к NSDictionary можно применять похожие методы:

+ (id)dictionaryWithContentsOfFile:(NSString *)path

+ (id)dictionaryWithContentsOfURL:(NSURL *)aURL
- (BOOL)writeToFile:(NSString *)path atomically:(BOOL)flag

Более сложная ситуация

С простым разобрались. Хорошо, если NSArray (или другая коллекция) содержит в себе экземпляры классов, которые поддерживают NSCoding. А если в коллекции находится что-то созданное своими руками? Правильный ответ — нужно заставить «это» следовать NSCoding протоколу.

Предположим у нас есть наш красс Customer.  В объявлении надо написать, что он следует NSCoding. К примеру так:

@interface Customer : NSObject<NSCoding>

Далее нужно реализовать два метода — записи и чтения. Сначала рассмотрим метод записи. Предположим, что в классе Customer есть два поля — int m_ID и NSString* m_Name:

-(void) encodeWithCoder:(NSCoder *)aCoder {

[aCoder encodeInt:m_ID forKey:@"ID"];
[aCoder encodeObject:m_Name forKey:@"Name"];
}

Как видим, нужно просто поставить в соответствие каждому полю какой-либо ключ. Теперь чтение:

-(id) initWithCoder:(NSCoder *)aDecoder {

self = [super init];
m_ID = [aDecoder decodeIntForKey:@"ID"];
m_Name = [[aDecoder decodeObjectForKey:@"Name"] retain];
return self;
}

Просто «забираем» значения по ключам, которыми сохраняли.

Итог

Возможно, вы спросите — зачем? Ведь есть JSON и XML. Использование «родных» для MacOS X и iOS файлов plist дает прирост в скорости «парсинга», т.е. JSON и XML обрабатываются дольше, чем plist.

К тому же метод с NSCoding можно использовать при сохранение каких-либо данных внутри приложения.

Похожие статьи

  • Audio Unit в iOS. Часть 3, накладываем эффект Delay

  • Audio Unit в iOS. Часть 2, строим граф и проигрываем файлы

  • Audio Unit в iOS. Часть 1, введение.

  • Используем Emoji в своих приложениях

  • Как вводить в UITextField только цифры?

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *