<!-- Canonical: https://docs.shopstory.live/docs/guide/mobile-sdk-releases -->

# Mobile SDK: lifecycle и выпуск

## Версии

| Компонент | Документированная версия | Статус |
| --- | --- | --- |
| Native iOS | `0.2.0-preview.2` | Preview, exact pin |
| Flutter adapter | `0.2.0-preview.3` | Preview; native iOS `0.2.0-preview.2` |

Это версии, к которым относятся опубликованные примеры, а не обещание автоматической совместимости с будущими пакетами. Сверяйте README и CHANGELOG в выданном tag.

Preview может изменить API в следующем tag. Обновляйте пакет только после чтения changelog и migration notes; Flutter adapter и native dependency обновляйте согласованной парой. Политика стабильных версий описана в README пакета.

Для обновления:

1. Сравните API, требования к toolchain и known limitations старой и новой версии.
2. Зафиксируйте exact pin и обновите lockfiles.
3. Выполните чистую установку зависимостей и Release build.
4. Повторите приёмку ниже на поддерживаемом устройстве.
5. Выпускайте через feature flag приложения. Для rollback восстановите предыдущие принятые pins и сборку.

Remote policy может отключить SDK UI, но не заменяет rollback приложения.

## Состав работ для оценки

| Часть интеграции | Работа приложения | Что нужно до оценки |
| --- | --- | --- |
| Dependency | Подключить SDK, зафиксировать версию и настроить доступ в CI | Версия пакета и требования к toolchain |
| Configure | Настроить SDK без блокировки запуска приложения | `applicationId` и тестовая среда |
| Navigation | Сопоставить routes с `ShopStorySurface` и применять policy после переходов | Карта экранов, включая tabs и nested navigation |
| PDP | Передать `feedProductId`, отменять старый lookup и убирать прежний entrypoint | Товары с live, VOD и без видео |
| Playback | Удерживать одну session/coordinator и containers полного player и Follow Me | Структура UIKit/SwiftUI или Flutter host |
| Product action | Проверить ID и открыть PDP; при необходимости вызвать Cart API | Товарный route и решение по прямой корзине |
| Выпуск | Проверить Release build, физическое устройство и rollback | Матрица устройств и предыдущая принятая версия |

Для оценки прямой корзины нужны контракт Cart API и поведение при отказе. Базовый переход на PDP от Cart API не зависит.

## Идентификатор товара

`feedProductId` связывает каталог клиента, ShopStory, PDP и product action. Храните его строкой без потери ведущих нулей. Если система магазина использует другой ключ, преобразование выполняет приложение.

Не используйте внутренний ShopStory `productId` для native routing. URL в product action — справочное поле; он не должен управлять переходами внутри приложения. Различия ID описаны в [таблице идентификаторов](<https://docs.shopstory.live/docs/resources/glossary#%D0%B8%D0%B4%D0%B5%D0%BD%D1%82%D0%B8%D1%84%D0%B8%D0%BA%D0%B0%D1%82%D0%BE%D1%80%D1%8B>).

## Product actions, корзина и остаток

Плеер передаёт намерение открыть товар или добавить его в корзину. Приложение и commerce-система ритейлера проверяют товар и выполняют действие.

1. Приложение получает типизированное действие и проверяет непустой `payload.feedProductId`. При отсутствии ID commerce action отклоняется без перехода и изменения корзины.
2. Native catalogue подтверждает, что товар существует и доступен в нужном регионе или магазине.
3. Для прямой корзины приложение вызывает свой stock/cart API с текущей сессией покупателя.
4. Merchant UI считает cart-команду успешной только после подтверждённого изменения корзины.
5. Если прямая корзина не подключена, обработчик приложения открывает нативную PDP.

В native iOS действие приходит через delegate без completion. Flutter handler возвращает адаптеру типизированный результат для host-side lifecycle, но этот результат не передаётся обратно в embedded player как подтверждение корзины. Поэтому состояние кнопки в player и аналитическое событие не доказывают изменение корзины.

В базовом сценарии приложение открывает нативную PDP для обоих действий. Прямую корзину включайте только по контракту из документации к поставленной версии. Подтверждённый результат добавления показывает интерфейс ритейлера. Плеер ShopStory не хранит состояние корзины.

Проверка остатка внутри cart-команды приложения входит в native cart flow. Показ наличия по выбранному магазину внутри плеера до нажатия «Купить» требует отдельного проектного контракта с ShopStory, согласованного до оценки разработки. В приведённый mobile host contract эта возможность не входит. [Контракт Web SDK](<https://docs.shopstory.live/docs/guide/product-availability>) относится к web-интеграции; его callbacks и объект `actions` в native iOS или Flutter не переносятся.

Между синхронизациями фида данные каталога устаревают, поэтому окончательное решение о покупке остаётся за cart-командой приложения.

## Lifecycle

- SDK сохраняет одну playback session при переходе full-screen → native PDP → follow-me.
- Приложение сообщает реальную видимую поверхность после push, replace, pop и изменения tab, затем синхронизирует активную сессию с SDK policy.
- Неизвестная поверхность блокируется до явного разрешения.
- Cart, checkout, payment, auth и profile исключаются из follow-me по runtime policy.
- При background media ставится на паузу; отдельный background audio contract отсутствует.
- При закрытии или отключении policy container удаляется, player teardown завершается, handlers освобождаются.
- Ошибка SDK оставляет PDP, navigation, cart и checkout приложения рабочими.

`unavailable` — штатное состояние: для товара нет доступного live/VOD, поэтому entrypoint не показывается. При технической ошибке приложение записывает typed error в свой диагностический logger и удаляет пустой блок с PDP.

## Безопасность и данные

SDK владеет WebView-конфигурацией и проверяет HTTPS, exact origin, main-frame navigation, схему и размер сообщения. Не создавайте параллельный `WKWebView`, JavaScript bridge или URL-конструктор по фрагментам этой страницы.

Для интеграции native SDK использует:

- `applicationId` проекта;
- platform, SDK version и host app version;
- текущий `feedProductId`;
- player/preview URLs из ответа ShopStory;
- runtime policy и локальные lifecycle diagnostics.

Не передавайте в SDK access tokens, session cookies, платёжные данные, профиль, точную геопозицию, advertising ID или содержимое корзины. Web-плеер отправляет собственные события аналитики ShopStory; приложение ритейлера отвечает за аналитику нативной навигации и подтверждённого результата в своём commerce-интерфейсе.

Полный состав данных, включая аналитику embedded player, и `PrivacyInfo.xcprivacy` проверяются по privacy-документации выбранной версии.

Подробнее: [Безопасность интеграции](<https://docs.shopstory.live/docs/operations/security>).

## Приёмка перед выпуском

- Exact package version зафиксирована в lockfile; для Flutter там же зафиксирована совместимая native dependency.
- `feedProductId` совпадает в mobile catalogue и товарном фиде, включая ведущие нули.
- Для товара с видео entrypoint открывает live и VOD; для товара без видео UI отсутствует без пустого места.
- Смена товара отменяет предыдущий lookup и не показывает устаревший preview.
- Product action открывает правильную native PDP.
- Для прямой корзины merchant UI показывает success только после подтверждения cart API; состояние кнопки в player не используется как подтверждение.
- Follow-me сохраняет ту же сессию, соблюдает safe area и скрывается на cart/checkout/payment/auth/profile.
- Background ставит media на паузу; close и remote disable полностью освобождают player UI.
- Потеря сети и некорректная конфигурация не блокируют PDP, navigation или checkout.
- Проверены accessibility labels, Dynamic Type/масштаб текста и целевые orientation.
- На поддерживаемом физическом iPhone проверены live, VOD, звук, background/foreground, product handoff и follow-me.
- Release build и rollback на предыдущую принятую exact version проверены до rollout.

## Что получить от ShopStory

Команда ShopStory передаёт назначенным инженерам клиента:

- доступ к репозиторию пакета без секретов в исходном коде;
- точную неизменяемую версию; для Flutter — совместимую пару Flutter/native зависимостей;
- требования конкретной версии;
- `applicationId`, тестовые товары и ожидаемое состояние live/VOD;
- route-to-surface map и выбранный cart contract;
- acceptance checklist, rollout, rollback и канал поддержки.

При обращении в поддержку приложите SDK version, Xcode/Flutter/iOS version, host app version, `applicationId`, затронутый `feedProductId`, время проблемы и типизированную ошибку. Не отправляйте auth tokens, session cookies или полные production logs.

Подробнее о [данных и событиях mobile](<https://docs.shopstory.live/docs/guide/analytics-mobile>).
