Расскажите про опыт работы с кэшированием офлайн-режима
Что проверяют
Умеете ли вы строить приложение, для которого сеть это не обязательное условие, а необязательный ресурс. Смотрят выбор хранилища, стратегию обновления и, главное, что происходит с изменениями, которые пользователь сделал без сети.
Как отвечать
Опишите три уровня:
- сетевой кэш.
URLCacheвместе сETagиIf-None-Matchдаёт почти бесплатное переиспользование ответов, аcachePolicyзапроса задаёт поведение при отсутствии сети; - хранилище. Core Data или SwiftData для связанных сущностей,
GRDBили чистый SQLite там, где нужен контроль над запросами, файлы в каталогеCachesдля картинок и вложений.NSCacheживёт только в памяти и чистится системой сам; - очередь исходящих изменений. Локальная запись сразу, отправка при появлении сети, идемпотентный ключ на запросе и понятная стратегия разрешения конфликтов.
Дальше механика: следить за сетью через NWPathMonitor, фоновую синхронизацию отдавать BGTaskScheduler и фоновой сессии URLSession, писать в Core Data из фонового контекста, а в основной приносить изменения слиянием. Отдельно скажите про миграции: кэш переживает обновление приложения, и несовместимая модель ломает запуск.
Хорошо звучит и то, как состояние показано в интерфейсе: данные из кэша с отметкой времени, признак неотправленных изменений, ошибка вместо бесконечного индикатора загрузки.
Где спотыкаются
Складывают кэш в Documents. Этот каталог уходит в резервную копию и не очищается системой при нехватке места, поэтому кэш растёт, а пользователь видит гигабайты в настройках. Для такого есть Caches и флаг исключения из бэкапа.
Второе: опрашивают сеть таймером и принимают решение по флагу доступности. Флаг говорит о маршруте, а не о том, что сервер отвечает, поэтому запрос всё равно надо пробовать и корректно обрабатывать отказ.
Третье: работают с Core Data из одного главного контекста. Запись пачки объектов подвешивает интерфейс, а параллельные правки без политики слияния дают конфликты, которые всплывают только на устройстве пользователя.