При разработке практически любого приложения рано или поздно возникает необходимость сохранить его настройки, будь то текущая версия или настройки внутриприложения.
Что в этом случае делает разработчик? Сохраняет данные настроек через NSUserDefaults и делает все правильно.
Когда настроек действительно много, управлять ими становится неудобно.
В приложении Peers.TV мы использовали следующий трюк — архиваторы и протокол NSCoding. Это помогло нам объединить некоторые настройки в рамках одного домена и немного упростить работу с ними.
Для справки.
Приложение Peers.TV предназначено для просмотра ТВ онлайн и архивных сериалов.
Сегодня существует 30 каналов различной тематики.
В нем есть программа на неделю вперед, напоминания о времени переноса, внутриигровые покупки, архив — все это требует своих отдельных настроек, что и привело нас к протоколу NSCoding. Рассмотрим реализацию протокола NSCoding на примере настроек блокировки приложения от нежелательного доступа третьих лиц.
Реализация работы с настройками вынесена в отдельный класс Singleton, а сами настройки реализуются через свойства этого класса.
Предположим, у нас есть 5 различных настроек, представленных следующим образом:
Соответственно, для каждой настройки нам нужно будет объявить один дополнительный ключ.@property (nonatomic, assign) BOOL isPasscodeEnabled; @property (nonatomic, assign) NSUInteger attemptCount; @property (nonatomic, assign) NSTimeInterval checkInterval; @property (nonatomic, strong) NSDate *nextCheckDate; @property (nonatomic, strong) NSString *applicationVersion;
Код, отвечающий за инициализацию и реализацию свойств, также опущен и будет показан ниже.
Теперь вернемся к протоколу NSCoding. Этот протокол позволяет указать порядок сериализации и десериализации данных объекта.
Чтобы реализовать этот протокол, вам необходимо реализовать 2 метода: - (void)encodeWithCoder:(NSCoder *)aCoder;
- (id)initWithCoder:(NSCoder *)aDecoder;
Нам также понадобятся классы NSKeyedArchiver и NSKeyedUnarchiver, которые сделают всю работу за нас.
Стоит отметить, что эти классы допускают сериализацию и десериализацию данных по ключам.
Далее мы опишем класс, который объединит настройки блокировки приложения.
Интерфейс: @interface PassCodeSettings: NSObject<NSCoding>
@property (nonatomic, assign) BOOL isPasscodeEnabled;
@property (nonatomic, assign) NSUInteger attemptCount;
@property (nonatomic, assign) NSTimeInterval checkInterval;
@property (nonatomic, strong) NSDate *nextCheckDate;
@end
Выполнение: @implementation PassCodeSettings
- (id)initWithCoder:(NSCoder *)aDecoder {
self = [super init];
if (self) {
_attemptCount = [aDecoder decodeIntegerForKey:@"attemptCount"];
_isPasscodeEnabled = [aDecoder decodeBoolForKey:@"isPassCodeEnabled"];
_checkInterval = [aDecoder decodeDoubleForKey:@"checkInterval"];
_nextCheckDate = [NSDate dateWithTimeIntervalSince1970:[aDecoder decodeDoubleForKey:@"nextCheckDate"]];
}
return self;
}
- (void)encodeWithCoder:(NSCoder *)aCoder {
[aCoder encodeBool:_isPasscodeEnabled forKey:@"isPassCodeEnabled"];
[aCoder encodeInteger:_attemptCount forKey:@"attemptCount"];
[aCoder encodeDouble:_checkInterval forKey:@"checkInterval"];
[aCoder encodeDouble:[_nextCheckDate timeIntervalSince1970] forKey:@"nextCheckDate"];
}
@end
Теперь настройки блокировки приложения вынесены в отдельный класс, соответствующий протоколу NSCoding. С помощью NSKeyedArchiver, NSKeyedUnrachiver мы можем реализовать сохранение произвольного класса в настройках.
Инициализация и сохранение настроек будет выглядеть так: - (id)init {
self = [super init];
if (self) {
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
_applicationVersion = [defaults stringForKey:kApplicationVersion];
NSData *passCodeData = [defaults dataForKey:kPasscodeSettings];
if (passCodeData) {
_passCodeSettings = [NSKeyedUnarchiver unarchiveObjectWithData:passCodeData];
} else {
_passCodeSettings = [PassCodeSettings new];
}
}
return self;
}
- (void)savePasscodeSettings {
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:[NSKeyedArchiver archivedDataWithRootObject:_passCodeSettings] forKey:kPasscodeSettings];
[defaults synchronize];
}
Стоит упомянуть несколько хитростей, которые могут облегчить вам жизнь:
1. Чтобы избежать сохранения настроек вручную с помощью метода savePasscodeSettings, можно реализовать мониторинг свойств на основе принципов KVO (Key Value Observing) или использовать уведомления жизненного цикла приложения.
2. Вы также можете отправлять уведомления об изменении настроек через NSNotificationCenter. Ссылка к интересная статья о протоколе NSCoding от небезызвестного Майка Эша.
Чего мы достигли: — Мы перенесли часть настроек в один домен, теперь мы можем группировать методы работы с данными домена внутри этого домена; — Стало немного проще работать с настройками.
Удивительно, но мало кто использует NSCoding для сериализации данных в своих проектах, хотя, на мой взгляд, это незаслуженно.
Конечно, я могу судить об этом только по проектам с открытым исходным кодом.
Этот подход не является панацеей, это один из многих других вариантов.
Он хорошо вписался в структуру нашего приложения и облегчил нам разработку.
Вот и всё, исходный код этого примера доступен.
Здесь .
Наше приложение Peers.TV, в котором использовалось NSCoding, можно посмотреть в AppStore:
Глеб Пинигин, iOS-разработчик
Теги: #Разработка для iOS #peers.tv #NSCoding #покупка в приложении #программирование #Разработка для iOS
-
Луа На Stm32
19 Oct, 24 -
Как «Зашить» Сетчатку И Нужно Ли Это Делать?
19 Oct, 24 -
Dagazserver: Знакомьтесь, Гарбо Чесс
19 Oct, 24 -
Интернет-Математика От Яндекса
19 Oct, 24 -
Цитировать
19 Oct, 24 -
Гаджетзависимость: Обзор Одной Коллекции
19 Oct, 24