· Workflow · 9 мин. чтения

Скриншоты Expo App Store: почему EAS Submit их пропускает и как всё-таки их подготовить (2026)

Скриншоты Expo App Store: почему EAS Submit их пропускает и как всё-таки их подготовить (2026)
TL;DR. EAS Submit загружает .ipa/.aab в App Store Connect и Play Console — и этим ограничивается. Он не генерирует, не загружает и не управляет скриншотами магазина. Поэтому Expo-разработчикам нужен отдельный пайплайн для скриншотов: захват кадров из dev/preview-сборки (симулятор, эмулятор или Maestro/Detox), а затем компоновка и локализация маркетинговых панелей. В этой статье честно разобраны команды для захвата, а также где в эту схему вписывается инструмент компоновки — сам он ничего не захватывает.

Если ты публикуешь Expo-приложение, релизный путь, скорее всего, заканчивается одной командой: eas submit. Она берёт собранный EAS бинарник и передаёт его Apple или Google. Чисто, предсказуемо, надёжно. Потом открываешь App Store Connect, чтобы сделать сборку активной — и видишь пустые слоты для скриншотов. Каждый раз.

Многих это застаёт врасплох, потому что EAS создаёт ощущение, что делает всё. Собирает, подписывает, отправляет. Неужели со скриншотами тоже? Нет — и документация прямо об этом говорит. Это не баг и не недостающая функция, на которую можно жаловаться — просто это не входит в задачи EAS Submit.

Что EAS Submit делает (и чего не делает)

EAS Submit — это сервис доставки бинарников. Он загружает ровно одно: скомпилированный архив приложения — .ipa для iOS, .aab для Android — в пайплайн обработки магазина. Документация Expo чётко обозначает границу:

«EAS Submit загружает бинарник, но не управляет метаданными листинга магазина, скриншотами или примечаниями к релизу.»

Есть сопутствующий инструмент — EAS Metadata, который умеет автоматизировать часть листинга App Store: название приложения, подзаголовок, локализованные описания, ключевые слова, ссылки на поддержку — из конфиг-файла. Он действительно полезен и стоит того, чтобы его настроить. Но прочитай его scope внимательно: скриншотов там нет. EAS Metadata пушит текст, не изображения. Скриншоты в обоих магазинах по-прежнему твоя забота.

Таким образом, проблема скриншотов в Expo распадается на две отдельные задачи — и полезно держать их в голове раздельно:

  1. Захват — получить сырые кадры реальных экранов приложения из сборки.
  2. Компоновка и локализация — превратить сырые кадры в оформленные, подписанные, многоязычные маркетинговые панели, которые магазины реально показывают.

EAS не делает ни того ни другого. Собственное руководство Expo по ассетам магазина предлагает захватывать кадры самостоятельно и оформлять панели в таком инструменте, как Figma. Разберём обе задачи с конкретными командами.

Задача 1: захват кадров из dev- или preview-сборки

Нужны скриншоты реального приложения — значит, приложение должно где-то работать и его нужно захватить. Для Expo это dev-клиент или preview-сборка — не Expo Go, потому что Expo Go показывает обёртку Expo и нативная конфигурация может отличаться. Собирай и запускай локально стандартными командами Expo:

  • npx expo run:ios — пребилдит нативный iOS, компилирует и запускает приложение в iOS Simulator.
  • npx expo run:android — то же самое для Android-эмулятора (или подключённого устройства).

Когда приложение открыто в iOS Simulator, захват — одна команда в терминале Mac:

xcrun simctl io booted screenshot home.png

booted адресуется к текущему запущенному симулятору и записывает попиксельно точный PNG в рабочую директорию. Два флага важны для работы с магазином: --type=png (по умолчанию, и именно это нужно магазинам) и --mask=ignored против --mask=black — маска управляет тем, рендерятся ли вырез и скруглённые углы в изображение. Для загрузки в App Store обычно нужны плоские прямоугольные пиксели — рамку устройства добавишь позже при компоновке, так что захват без маски — как правило, правильная отправная точка.

На Android захватывай прямо с эмулятора (или устройства) через adb:

adb exec-out screencap -p > home.png

Используй exec-out, а не shell screencap. Обычный shell-путь пропускает PNG через псевдотерминал, который на некоторых конфигурациях искажает бинарник (получаешь повреждённый файл с лишними символами возврата каретки); exec-out передаёт байты напрямую и работает надёжно. Если запущено несколько эмуляторов, адресуйся к конкретному через adb -s <serial> из adb devices.

Вот и весь набор для ручного захвата: две команды, по одной на платформу, без зависимостей помимо Xcode и Android SDK, которые у тебя уже есть для нативной сборки Expo.

Задача 1, автоматизированная: Maestro или Detox

Вручную переходить к нужному экрану и запускать команды нормально для небольшого числа кадров. Но когда у тебя восемь экранов для двух классов устройств или нужно пересоздавать скриншоты при каждом релизе, чтобы они не расходились с реальным UI — автоматизируй захват с помощью end-to-end инструмента тестирования, который умеет управлять приложением и делать снимки.

Maestro — тот инструмент, к которому сам Expo обращается в задокументированных примерах EAS Workflows. Флоу пишутся на простом YAML, порог входа низкий. Флоу, который доводит приложение до нужного экрана и делает снимок, выглядит так:

appId: com.you.yourapp --- - launchApp - tapOn: "Get started" - assertVisible: "Your dashboard" - takeScreenshot: dashboard

Запускается командой maestro test flows/home.yaml. Команда takeScreenshot записывает PNG в директорию вывода тестов (укажи MAESTRO_TESTS_DIR в нужное место). Те же флоу работают в CI на EAS Workflows — задокументированный пример Expo собирает .apk с профилем сборки e2e-test и затем запускает флоу из .maestro/ против него — так что захват скриншотов можно подключить к той же задаче, что выполняет e2e-тесты.

Detox — ещё один проверенный вариант, с более строгим и программным JavaScript API:

const path = await device.takeScreenshot('dashboard');

Будь честен с собой насчёт настройки Detox с Expo. Detox официально не поддерживает Expo. На практике это работает, если выполнить npx expo prebuild для генерации нативных проектов и собрать release-стайл клиент (не dev-клиент) со встроенным JS-бандлом — затем навести Detox на этот бинарник. Движущихся частей больше, чем в YAML-флоу Maestro, а выигрыш — более строгая синхронизация и assertion API Detox. Если Detox уже используешь — задействуй его для захвата; если выбираешь с нуля и цель — скриншоты магазина, Maestro — более лёгкий путь.

Задача 1, вручную: правильный выбор для редких релизов

Автоматизация окупается, когда выпускаешь часто. Если у тебя один-три релиза в год — а это большинство инди Expo-приложений — настройка Maestro-флоу или Detox-конфига ради захвата скриншотов стоит усилий, которые едва ли отобьются. При такой периодичности просто:

  1. Запусти сборку командой npx expo run:ios / run:android, наполни её реалистичными демо-данными.
  2. Перейди к каждому ключевому экрану вручную.
  3. Сними каждый командой simctl / adb выше.

Двадцать минут кликов лучше, чем полдня над тестовым окружением, о котором ты забудешь к следующему релизу. Ничего зазорного в ручном захвате — магазины не знают, как был сделан PNG.

Задача 2: компоновка и локализация на 50 языков

Вот та часть, которую инструменты захвата намеренно не затрагивают — и именно по ней магазины тебя оценивают. Сырой PNG из simctl — это UI твоего приложения на белом фоне. То, что поднимает позиции в поиске и конвертирует на странице продукта, — это маркетинговая панель: скриншот в рамке устройства, на брендовом фоне, с однострочной подписью, объясняющей, зачем этот экран важен — обычно в виде многопанельной карусели, читающейся слева направо. А в App Store скриншоты локализуются по размеру устройства и по языку, так что серьёзный запуск — это десятки вариантов, а не пять.

Именно здесь в схему вписывается Mokbi — и стоит чётко обозначить границу. Mokbi не захватывает приложение — исходные кадры ты по-прежнему делаешь командами Expo выше. Он берёт эти кадры и позволяет тебе прямо в браузере: помещать их в настоящие рамки устройств, добавлять подписи и градиентные фоны, выстраивать многопанельные карусели, переводить тексты подписей на 50 языков одним кликом и пакетно экспортировать во всех размерах App Store и Play Store за один проход. Дизайн бесплатен с водяным знаком предпросмотра; безлимитный экспорт доступен по подписке — Solo €29.99/mo (1 приложение) или Studio €49.99/mo (до 5 приложений), без разовой покупки. Он заменяет шаг с шаблоном Figma, который руководство Expo вскользь упоминает — не больше и не меньше.

Реалистичный совмещённый воркфлоу

  1. Собери dev/preview-клиент. npx expo run:ios и npx expo run:android, наполни хорошими демо-данными.
  2. Захвати исходные кадры. Вручную через xcrun simctl io booted screenshot и adb exec-out screencap -p, или автоматически через Maestro takeScreenshot / Detox device.takeScreenshot — в идеале на EAS Workflows, чтобы пересоздавались при каждом релизе.
  3. Скомпонуй маркетинговые панели. Добавь рамки устройств, подписи и оформи карусель из сырых кадров.
  4. Локализуй и пакетно экспортируй. Переведи подписи на нужные языки, экспортируй во всех требуемых размерах для обоих магазинов.
  5. Загрузи ассеты листинга. Скриншоты в App Store Connect и Play Console; если используешь EAS Metadata — дополни текстовые поля с его помощью.
  6. Отправь бинарник. eas submit — единственный шаг, который EAS действительно берёт на себя.
  7. Следующий релиз: перезахвати изменившиеся экраны, открой сохранённый проект компоновки, замени кадры, переэкспортируй. Подписи и переводы остаются на месте.

Когда можно обойтись без автоматизации

Maestro или Detox для захвата стоит использовать, когда расхождение скриншотов — реальная проблема: выпускаешь еженедельно, UI меняется постоянно или поддерживаешь много приложений и не можешь позволить себе устаревшие ассеты магазина. В таких случаях пересоздание кадров в CI окупается — и история с инструментами для скриншотов React Native (которую Expo наследует) стоит изучить.

Всем остальным — тем, кто выпускает раз в квартал — автоматизация не нужна. Ручной захват двумя командами в терминале, затем браузерная компоновка и локализация — и к вечеру у тебя готовый, многоязычный листинг с нулём зависимостей между релизами. Подбирай инструменты под свой ритм, а не под то, что красиво смотрится на CI-дашборде.

Бинарная часть в любом случае решена: eas submit её берёт на себя. Перед загрузкой проверь скриншоты на соответствие актуальным требованиям магазина — Apple отклоняет заявку из-за одного пикселя погрешности — а остальное в запуске — это просто дизайн.

Что читать дальше

Открыть редактор →