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

# Mobile SDK для Flutter на iOS

Проверенная пара: `shopstory_player_flutter 0.2.0-preview.3` и `ShopStoryPlayerSDK 0.2.0-preview.2`. Документированный baseline — Flutter 3.24.5 / Dart 3.5.4, iOS 15+ и Xcode 16+. Android adapter в эту поставку не входит.

## Установить adapter

Получите read-only доступ к Flutter и native пакетам. В `pubspec.yaml` добавьте Git dependency с URL из выданной инструкции и `ref: 0.2.0-preview.3`. Сохраните `pubspec.lock` и native lockfile.

Для Flutter 3.24 используется CocoaPods; точный native pin указан в инструкции adapter. Для проекта с включённым Swift Package Manager используйте настройки из той же версии. Не меняйте способ подключения всего приложения ради примера.

После установки выполните `flutter pub get` и сборку iOS. Доступ к приватным зависимостям должен работать и на машине разработчика, и в CI.

## Запустить starter

[Скачать Flutter starter](<https://docs.shopstory.live/downloads/shopstory-flutter-starter.zip>). README содержит команды генерации iOS host, подключения локальной копии adapter и запуска с `--dart-define`. Проект не содержит клиентских идентификаторов.

Передайте выданные `applicationId` и тестовый `feedProductId`. Для товара с видео должен появиться SDK preview; его нажатие открывает player. Товар без видео оставляет обычную PDP. Product action открывает PDP приложения, а не подтверждает корзину.

## Подключить приложение

```dart
final shopStory = ShopStoryPlayerFlutter.instance;
var shopStoryConfigured = false;

if (shopStory.isSupportedPlatform) {
  try {
    await shopStory.configure(applicationId: applicationId);
    shopStoryConfigured = true;
  } catch (error, stackTrace) {
    FlutterError.reportError(
      FlutterErrorDetails(exception: error, stack: stackTrace),
    );
  }
}

final observer = ShopStoryNavigatorObserver(
  surfaceForRoute: mapRouteToShopStorySurface,
);

Future<ShopStoryProductActionResult> openNativeProduct(
  ShopStoryProductAction action,
) async {
  final id = action.payload.feedProductId;
  if (id == null || id.trim().isEmpty) {
    return const ShopStoryProductActionFailed(
      ShopStoryProductActionFailureReason.invalidPayload,
    );
  }

  final accepted = await openProductByFeedId(id);
  return accepted
      ? const ShopStoryProductActionOpenedProduct()
      : const ShopStoryProductActionFailed(
          ShopStoryProductActionFailureReason.operationFailed,
        );
}

final productActionRegistration = shopStoryConfigured
    ? shopStory.registerProductActionHandlers(
        onOpenProduct: openNativeProduct,
        onAddProduct: openNativeProduct,
      )
    : null;

MaterialApp(
  navigatorObservers: shopStoryConfigured ? [observer] : [],
  home: const AppRoot(),
);

final productScreen = shopStoryConfigured
    ? ShopStoryProductDetailScope(
        feedProductId: product.feedProductId,
        child: ProductDetailView(product: product),
      )
    : ProductDetailView(product: product);
```

Один root `Navigator` должен использовать observer. Для declarative router, tabs и nested navigator передавайте текущую поверхность из существующего state owner через `setCurrentSurface`.

До открытия ShopStory UI зарегистрируйте обработчики в integration root. В примере оба действия открывают нативную PDP: у `onAddProduct` нет автоматического перехода через `onOpenProduct`. Если поступившее действие не имеет обработчика, адаптер отклоняет его.

`openProductByFeedId` принадлежит приложению и возвращает `true`, когда router принял переход. Не ожидайте закрытия открытой страницы: например, `Future` из `Navigator.push` завершается после возврата с неё. Возвращайте `ShopStoryProductActionOpenedProduct` после принятого перехода. Для прямой корзины замените `onAddProduct` отдельным обработчиком и возвращайте `ShopStoryProductActionSucceeded` только после подтверждения cart-команды. Регистрацию удерживает root owner; при его освобождении вызовите `productActionRegistration?.dispose()`.

## Следующий шаг

Проверьте [lifecycle и выпуск](<https://docs.shopstory.live/docs/guide/mobile-sdk-releases>) и [аналитику приложения](<https://docs.shopstory.live/docs/guide/analytics-mobile>).
