· Workflow · 9 分钟阅读

如何为 React Native 应用创建 App Store 截图(2026)

如何为 React Native 应用创建 App Store 截图(2026)
TL;DR. React Native 没有官方截图生成流程。捕获原始帧的可行选项有:Fastlane(iOS 用 XCUITest,Android 用 screengrab/Espresso)、Detox(专为 React Native 设计,是三者中最易上手的),或直接从模拟器手动截图。无论选哪种,得到的都只是裸应用截图——将这些截图转化为带有文案、设备框架和多语言版本的商店就绪轮播图,是单独的营销步骤。对于大多数一年发几次版的团队,手动截图加浏览器组合比花一天配置 Fastlane 更划算。

当你第一次把 React Native 应用发布到 App Store 时,没人告诉你一件事:商店需要的截图没有内置的生成方式。原生 iOS 开发者可以用 Xcode 的 UI 测试录制器;原生 Android 开发者有内置于构建系统的 Espresso。React Native 架构在两者之上,应用逻辑运行在 JavaScript 中——这些工具根本感知不到你的 JS 存在。需要你自己来弥合这个缺口。

本文梳理了在新架构时代(React Native 0.7x 及以上,2026 年)真正可行的方案,并附上具体命令。对于每个选项的代价,本文会如实说明,因为每种方案都有真实的代价。随后会介绍截图之后的部分——营销组合与本地化——这是一个真正独立的问题,无论你用哪种方式获取源帧都如此。

真正的问题:没有官方流程

App Store Connect 要求截图符合精确的像素尺寸,理想情况下每种设备类型和每种支持的语言各一套。Google Play 有其自己的尺寸要求。原生 iOS 项目可以通过 XCUITest 驱动模拟器并导出帧;React Native 技术上也可以,但你编写的测试运行在原生 shell 上——编译后的二进制文件——而非直接运行在 JavaScript 组件上。你在自动化一个恰好渲染了你的 JS 的黑盒。

这个区别比听起来更重要。它意味着截图自动化会因与你的 React 代码毫无关系的原因失败(Metro 打包器没在运行、模拟器卡在权限弹窗上、原生构建与你的 JS 产生了偏差),也意味着学习曲线是两个原生测试框架的曲线,而非你熟悉的 React Native 技术栈。应对这一问题有三种可行路径,根据你的发版频率来选择。

选项 1 — fastlane snapshot(iOS)和 screengrab(Android)

fastlane 是主流的开源移动端自动化框架,其截图模块是最经过实战验证的选项。对于 React Native 来说,配置工作量也是最大的,因为它是为原生项目设计的,对 React Native 只是有限兼容。

iOS,通过 snapshot在 Xcode 中添加 UI 测试目标,用 Swift 编写 XCUITest 用例,驱动应用到每个需要截图的界面。fastlane snapshot init 会在 fastlane/ 目录下生成 SnapfileSnapshotHelper.swift。测试中调用 setupSnapshot(app),启动应用,然后在每个状态调用 snapshot("01_home")。从终端运行 fastlane snapshot——不能在 Xcode 内部运行,否则输出不正确。它会遍历 Snapfile 中配置的每个模拟器和语言,将 PNG 写入 fastlane/screenshots/

React Native 特有的麻烦:snapshot 启动的是编译后的应用,调试模式下需要 Metro 打包器已在运行。因此你的 Fastfile(或封装脚本)必须先启动 Metro——常见做法是在调用 snapshot 前在后台 tmux 会话中启动 npx react-native start,完成后再关闭。使用内嵌了 JS bundle 的发布版构建可以避免这个问题,但每次运行都需要完整的发布构建。

Android,通过 screengrab完全不同的框架:screengrab 使用 Espresso。在 JUnit 仪器化测试中加入 Screengrab.screenshot("name") 调用,声明所需权限(DISABLE_KEYGUARDWAKE_LOCKCHANGE_CONFIGURATION 及存储权限),用 ./gradlew assembleDebug assembleAndroidTest 构建调试 APK 和测试 APK,然后运行 fastlane screengrab。输出保存在 fastlane/metadata/android/。与 iOS 一样,Metro 和模拟器必须提前启动——screengrab 不会替你启动它们。

优势:

  • 集成 CI,不会与应用脱节。接入流水线后,截图在每次发布构建时自动重新生成,始终与实际应用保持同步。
  • 真实的逐语言渲染。每种语言都在配置了对应语言的模拟器/模拟器中运行,日期、数字和货币均原生渲染,而非在设计工具中伪造。
  • 免费开源,成熟稳定。无需订阅,社区庞大,常见故障模式有充分记录。

劣势(请诚实面对):

  • 需要维护两套原生测试套件。iOS 用 Swift 编写 XCUITest,Android 用 Kotlin/Java 编写 Espresso/JUnit——对 React Native 开发者来说,可能是两套陌生的技术栈。
  • 测试的是原生 shell,而非你的 JS 逻辑。测试断言的是渲染后的原生视图,并不感知你的组件树。
  • 初次配置需要一两天,而 Metro 打包器的启停操作是 CI 不稳定的持续来源。
  • 输出为原始帧。没有文案、没有设备框架、没有渐变、没有轮播图——只有裸应用界面,分辨率与模拟器一致。
  • iOS 需要 Mac。模拟器依赖 Xcode。

关于组合步骤的详细对比,参见 fastlane snapshot 与无代码 App Store 截图工具对比,以及 Mokbi vs Fastlane 对比

选项 2 — Detox 截图(专为 React Native 设计)

Detox 是专为 React Native 打造的灰盒端到端测试框架,由 Wix 团队开发。如果你已经用 Detox 做 e2e 测试,截图几乎是零边际成本,而且学习曲线正是你本来就该走的那条——它是 JavaScript API,而非 Swift 或 Kotlin。

截图调用只需在任意测试中写一行:

// full screen
const path = await device.takeScreenshot('01_home');

// a single element
await element(by.id('paywallRoot')).takeScreenshot('paywall');

这些图片是否作为产物保留,由 --take-screenshots 标志控制(nonefailingmanualall),在 .detoxrc.js 中配置。在 manualall 模式下,通过的测试会将截图写入 <artifacts-location>/✓ [test name]/[name].png。你用和断言相同的 Detox 匹配器将应用驱动到各个状态,然后截图。

优势:

  • JavaScript API。用与应用相同的语言编写测试——无需维护第二套原生语言测试套件。
  • 灰盒,理解 React Native。Detox 与应用的 bridge/JSI 同步,等待其进入空闲状态,使截图的稳定性远高于 XCUITest 的盲等待。
  • 一套框架,双平台。同一个测试文件可同时截取 iOS 和 Android。
  • 如果你已经在做 e2e 测试,几乎已经有了。增量成本极低。

劣势:

  • 从零搭建 Detox 并不简单——需要原生构建配置、专用测试构建和模拟器配置。如果你目前没有运行它,这是真实的投入。
  • 语言处理需要自己解决。Detox 不会像 snapshot 的 Snapfile 那样自动遍历所有 App Store 语言;需要自己编写语言切换脚本或以不同设置重新启动应用。
  • 输出仍然是原始帧。与 Fastlane 相同——裸应用界面,没有营销层。
  • 不同主机上的截图可能存在差异(Detox 已知问题),对 CI 中的截图对比有影响,但对商店素材无害。

选项 3 — 手动截图(最简单,且常被低估)

打开 iOS 模拟器或 Android 模拟器,手动将应用导航到每个界面,截取画面。在 iOS 上,模拟器中按 Cmd-S 可将正确尺寸的 PNG 保存到桌面;xcrun simctl io booted screenshot home.png 从终端实现相同效果,易于松散地脚本化。在 Android 上,模拟器的相机按钮或 adb exec-out screencap -p > home.png 均可截屏。实体设备也可以——截图后通过 AirDrop 或传输文件即可。

这个方式被低估了。它无需任何配置,不会在 CI 中出错(因为根本没有 CI),对于一年发几次版的应用,这确实是获取一组源帧最快的路径。缺点显而易见且真实存在:它是手动的,不会自动重新生成,一旦某个界面发生变化,截图就会过期直到重新补拍。对于五个界面的轮播图,每次发版大约需要十分钟——比维护一套一年只跑两次的测试自动化更划算。

常被忽视的环节:组合与本地化

三种选项有一个共同点:它们得到的都是裸应用截图,而裸应用截图并不能在商店中带来转化。真正能推动安装的 App Store 轮播图,需要在屏幕外包一层设备框架、在上方加一行说明收益的文案、背景不能是应用本身的白色,并且五个面板之间要有连贯性。上述任何截图工具都不能产生这些——它们止步于裸帧。这不是缺陷,而是另一项工作。

这正是 Mokbi 所处的环节,有必要说清楚边界:它负责截取源截图——那是模拟器、设备或上面的 Fastlane/Detox 的工作。它做的是随后的营销组合与本地化层:将原始帧拖入浏览器编辑器,套上真实设备框架,添加文案,排布多面板轮播图,一键将文案翻译为 50 种语言,并按每种商店尺寸批量导出。设计阶段免费(带水印预览);无限次导出与商店发布需订阅——Solo €29.99/mo(1 款应用)或 Studio €49.99/mo(最多 5 款应用),无一次性买断。它能无缝接入的原因在于:它解决的是截图流程根本没有尝试解决的问题——将一个 PNG 文件夹转化为本地化的商店就绪轮播图,无需打开 Photoshop,也无需为 50 种语言手动调整尺寸。

现实可行的组合工作流

  1. 截取源帧。从中选一:频繁发版用 Fastlane(snapshot + screengrab)跑 CI,已有 e2e 测试则用 Detox,不频繁发版则手动模拟器截图。输出:每个界面、每种设备的原始 PNG 文件夹。
  2. 组合、添加文案、套设备框架。将原始帧拖入浏览器编辑器,添加设备框架,撰写收益文案,搭建五面板轮播图,选取背景。
  3. 翻译。一键批量翻译文案至 50 种语言,再对你最关注的语言版本逐一人工审核。
  4. 批量导出。一次性导出每种语言在每种所需尺寸下的素材,同时覆盖 App Store Connect 和 Google Play。
  5. 下次发版时替换。重新截取变更的帧(重跑 Fastlane/Detox 或手动截图),重新打开保存的项目,替换截图,重新导出。文案和翻译工作已经完成。

什么时候可以跳过自动化

如果你每年发布一到三个版本——大多数独立 React Native 应用都属于这种情况——Fastlane 或 Detox 的配置成本几乎永远回不了本。花一天配置 XCUITest 和 Metro 启停操作,只为每年省两次十分钟的手动截图,这笔账算不过来。从模拟器手动截图,在浏览器中组合与本地化,总耗时比配置一次自动化还少。

自动化真正值回票价的情况是:你每周或每天发版,截图脱节成为反复出现的问题,或者你管理多款应用、每款的截图捕获成本在叠加。在这种规模下,CI 上的 Fastlane(或你技术栈中已有的 Detox)在截图步骤上是正确选择——但你仍然需要搭配浏览器组合工具来处理营销层,因为任何截图流程都无法产出完整的轮播图。

在导出任何内容之前,值得确认一下目标规格:你实际需要上传的 App Store 截图尺寸,以及会导致提交被拒的 App Store 截图要求。一次搞清楚这些,能省去一次与 App Review 的来回。

延伸阅读

打开编辑器 →