Практически каждое мобильное приложение получает из сети какие-то данные.
К сожалению, доступ к сети не всегда возможен и поэтому разработчику важно правильно реализовать сетевой кэш в приложении.
В связи с этим я решил написать серию статей о том, какие существуют методы реализации кэша и когда их использовать .
Итак, введение.
Стратегии кэширования Существует два подхода к кэшированию: кэширование по требованию и предварительное кэширование.
Кэширование по требованию позволяет просматривать ранее просмотренный контент в автономном режиме.
Данные, полученные от сервера, сохраняются на устройстве и по каждому запросу проверяется их актуальность.
Если данные актуальны, то они берутся с диска; если нет, то делается запрос на сервер.
Предварительное кэширование подразумевает, что все данные, которые могут понадобиться пользователю, будут немедленно получены и сохранены на диске.
Чтобы определить, какую стратегию кэширования использовать, необходимо понять, может ли потребоваться постобработка данных после их загрузки.
Постобработка включает в себя некоторую модификацию загруженных данных.
Например, изменить ссылки на HTML-странице, чтобы они указывали на изображения, кэшированные локально, и т. д. Где хранить кэш Приложения могут хранить информацию только в своей песочнице.
Поскольку кэшированные данные не генерируются пользователем, их следует хранить в NSCachesDirectory, а не в NSDocumentsDirectory. Хорошей практикой является создание отдельного каталога для всех кэшированных данных.
В этом примере создается каталог MyAppCache в папке Library/Caches:
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
NSString *cachesDirectory = [paths objectAtIndex:0];
cachesDirectory = [cachesDirectory stringByAppendingPathComponent:@”MyAppCache”];
Причина хранения кеша в папке «Библиотека/Кэши» заключается в том, что iCloud (и iTunes) исключает этот каталог из резервной копии.
А, следовательно, и без того ограниченное пространство в iCloud (на данный момент для бесплатного аккаунта это около 5 ГБ) не тратится на хранение ненужных данных.
Если ваше приложение активно кэширует, рекомендуется использовать память вместо диска и сбрасывать данные на диск при закрытии приложения.
Это связано с тем, что флеш-память iPhone имеет ограниченное количество циклов записи/чтения и перегружать ее нежелательно.
Как хранить кэш
Существует много разных способов хранения пользовательских данных на iOS. Лучше всего для кэширования подходят: NSKeyedArchiver, Core Data, SQLite, NSURLCache.
NSKeyedArchiver
Кэширование модели данных реализовано с помощью класса NSKeyedArchiver. Чтобы объекты модели можно было архивировать, классы модели должны реализовывать протокол NSCoding. А именно методы - (void)encodeWithCoder:(NSCoder *)aCoder;
- (id)initWithCoder:(NSCoder *)aDecoder;
Если класс реализует NSCoding, чтобы его заархивировать, просто вызовите один из следующих методов: [NSKeyedArchiver archiveRootObject:objectForArchiving toFile:archiveFilePath];
[NSKeyedArchiver archivedDataWithRootObject:objectForArchiving];
Первый метод создаст архивный файл по пути archiveFilePath. Второй метод вернет объект NSData. NSData обычно работает быстрее, поскольку для доступа к файлу не требуется дополнительных затрат, но данные будут храниться в памяти приложения.
Чтобы разархивировать модель из файла (или указателя на NSData), используется класс NSKeyedUnarchiver. Вы можете разархивировать данные одним из следующих способов: [NSKeyedUnarchiver unarchiveObjectWithData:data];
[NSKeyedUnarchiver unarchiveObjectWithFile:archiveFilePath];
Использование NSKeyedArchiver/NSKeyedUnarchiver требует, чтобы модели соответствовали протоколу NSCoding. Реализовать NSCoding очень просто, но если файлов много, это может занять много времени.
Поэтому лучше использовать какой-нибудь инструмент для автоматизации этого процесса.
Например, среда разработки Код приложения .
Основные данные
Для хранения данных в Core Data необходимо создать файл модели, содержащий описание Сущностей, а также связей между ними (Relationships), и написать методы сохранения и получения данных.Используя Core Data, можно получить по-настоящему автономный режим приложения, как это сделано в стандартных приложениях «Почта» и «Календарь».
При реализации предварительного кэширования необходимо периодически удалять ненужные данные.
В противном случае размер кэша начнет заметно расти, что приведет к потере производительности.
Синхронизация локальных изменений осуществляется путем отслеживания набора изменений и отправки их обратно на сервер.
Существует множество алгоритмов отслеживания наборов изменений, но лучше всего использовать тот, который работает в Git. Хотя Core Data можно использовать для кэширования по требованию, лучше этого не делать.
Основное преимущество Core Data заключается в том, что он обеспечивает доступ к свойствам модели без необходимости разархивировать все данные.
Однако сложность реализации Core Data в приложении перевешивает это преимущество.
Необработанный SQLite
Для работы с SQLite необходимо связать приложение с библиотекой libsqlite3, однако у этого подхода есть существенные недостатки.Все библиотеки sqlite3 и механизм реляционного сопоставления объектов (ORM) работают медленнее, чем Core Data. Кроме того, реализация sqlite3 в iOS не является потокобезопасной.
Поэтому, если вы не используете отдельно скомпилированную библиотеку sqlite3 (скомпилированную с флагом потокобезопасности), вы несете ответственность за обеспечение поточно-безопасного доступа для чтения и записи к базе данных sqlite3.
Поскольку Core Data может предложить гораздо больше функций (миграция данных, встроенная безопасность потоков и т. д.), рекомендуется избегать использования собственного SQLite в iOS.
NSURLCache
Идеально подходит для кэширования по требованию.Позволяет кэшировать данные, возвращаемые NSURLRequest, практически автоматически и требует минимум кода.
Всего пара строк и у вашего приложения появится дисковый кеш для запросов.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
К сожалению, он подходит только для REST-сервисов и при работе с некоторыми HTTP-заголовками возникают проблемы.
NSURLCache *URLCache = [[NSURLCache alloc] initWithMemoryCapacity:4 * 1024 * 1024
diskCapacity:20 * 1024 * 1024
diskPath:nil];
[NSURLCache setSharedURLCache:URLCache];
}
Заключение
Для реализации кэширования по требованию лучше использовать NSURLCache или NSKeyedArchiver. Реализация полноценного офлайн-режима требует работы с CoreData.
В следующей части я планирую подробнее рассмотреть работу с NSURLCache/NSKeyedArchiver и описать случаи, для которых они подходят.
Теги: #ios разработка #iOS разработка #Разработка мобильных приложений
-
Чем Вам Запомнился Volga Ctf 2020?
19 Dec, 24 -
Экономьте Память С Уксм
19 Dec, 24