Исходная ситуация - есть действующее iOS-приложение для полевых сотрудников (iOS 15-17, Swift, UIKit + часть экранов на SwiftUI). Пользователь может работать без связи, а данные об использовании и техпроцессе (события, тайминги, ошибки, параметры сессии) должны гарантированно доставляться на наш API, когда связь появится. Сейчас телеметрия отправляется напрямую через URLSession и регулярно теряется из-за офлайна, убийства приложения и конкуренции фоновых задач. Также появились требования по хранению чувствительных данных на устройстве и контролю объема. Задача - разработать и внедрить модульный iOS SDK (как Swift Package) для надежного сбора и доставки телеметрии. Техническая среда и ограничения - Swift 5.9+, Xcode 15+, iOS 15+. Запрещено подключать тяжелые аналитические SDK (Firebase/Amplitude и т.п.). Нельзя собирать рекламные идентификаторы и делать трекинг пользователя. Данные должны храниться локально ограниченное время и объем. Серверная часть уже есть - REST endpoint /v1/telemetry/batch принимает gzip JSON, авторизация через существующий access token из приложения (предоставим протокол для получения токена). Формат события фиксированный - id (UUID), ts (ISO8601), type (строка), payload (словарь), sessionId. Что нужно сделать - 1) Спроектировать архитектуру SDK - публичное API для логирования событий из приложения, внутренняя очередь, хранилище, доставка, ретраи. 2) Локальное хранилище очереди - выбрать и реализовать (Core Data или SQLite/GRDB без внешних сервисов). Требования - атомарность, устойчивость к крэшам, возможность выборки батчами, дедупликация по id. 3) Шифрование на устройстве - хранить payload в зашифрованном виде (AES-GCM), ключ хранить в Keychain, поддержать ротацию ключа без потери очереди. 4) Доставка - отправка батчей с gzip, ограничение размера батча (например 256 КБ) и общего размера очереди (например 20 МБ) с политикой вытеснения (drop oldest). Ретраи с экспоненциальной задержкой, джиттером и учетом кодов ответа сервера (429/5xx). Уважать режим Low Power Mode. 5) Фоновые сценарии - корректная работа при уходе в background и при убийстве приложения. Использовать BGTaskScheduler для периодической доставки, а также отправку при появлении сети. Не нарушать ограничения iOS по фоновой активности. 6) Наблюдение сети - Network.framework (NWPathMonitor) для триггера доставки при восстановлении соединения. 7) Интеграция в приложение - заменить текущую прямую отправку на SDK в 2-3 точках логирования (например ошибки, события навигации, системные тайминги). Предусмотреть thread-safe вызовы из разных потоков. 8) Тестирование - покрыть ключевые части unit-тестами (очередь, шифрование, формирование батча, политики ретрая). Добавить минимальные integration-тесты на мок сервер (URLProtocol) и проверку сценария офлайн-онлайн. Конкретный результат - репозиторий с Swift Package (источники, тесты), примером использования и инструкцией интеграции в существующее приложение, плюс MR/PR с подключением пакета и заменой старых вызовов отправки. Измеримые критерии приемки - - При включенном Airplane Mode события пишутся в очередь и не теряются после перезапуска приложения; после отключения Airplane Mode все накопленные события доставляются на endpoint максимум за 15 минут при активном использовании приложения. - Очередь ограничена по объему 20 МБ - при превышении удаляются самые старые события, приложение не падает и не зависает. - Payload на диске не хранится в открытом виде - проверка через инспекцию файлов контейнера (строки из JSON не читаются как plain text). - SDK не использует запрещенные сторонние аналитические сервисы и не запрашивает лишние разрешения. - Доставка выполняется батчами с gzip, корректно обрабатывает 429 и 5xx (ретраи), 4xx кроме 429 не ретраятся. - Unit-тесты запускаются в CI локально (xcodebuild test) и покрывают не менее 60% кода модуля доставки/очереди. Дополнительно - можно предложить оптимизацию формата (например, компактный JSON/CBOR), но итоговый wire-формат должен остаться JSON, как сейчас на сервере.