This documentation is available as Markdown for AI agents and LLMs. See the full Markdown index or append .md to any documentation URL.
在现有原生应用中使用 EAS Update
编辑页面
了解如何将 EAS Update 集成到你现有的原生 Android 和 iOS 应用中,以启用空中更新。
如果你的项目是一个 greenfield React Native 应用——也就是从一开始主要使用 React Native 构建,并且应用入口点本身就是 React Native,那么请跳过本指南,直接继续阅读 Get started with EAS Update。
本指南说明如何在现有原生应用中集成 EAS Update,这类应用有时也称为 brownfield app。本文假设你使用的是 Expo SDK 52 或更高版本,以及 React Native 0.76 或更高版本。
较旧的 Expo SDK 和 React Native 版本不提供相关说明。对于旧版本集成的额外手把手支持,仅可为企业客户提供(联系我们)。
以下说明可能并不适用于所有项目。将 EAS Update 集成到现有项目中的具体方式,在很大程度上取决于你的应用本身,因此你可能需要根据自己的独特配置调整这些说明。如果遇到问题,请 在 GitHub 上创建 issue 或提交 pull request 来建议改进本指南。
7 requirements
7 requirements
1.
你应该已经有一个安装并配置好 React Native、能够渲染根视图的 brownfield 原生项目。如果你还没有,请先阅读 React Native 文档中的 与现有应用集成 指南,然后再回到这里。
2.
你的应用必须使用 最新的 Expo SDK 版本及其所支持的 React Native 版本。
3.
从你的应用中移除任何其他更新库集成,例如 react-native-code-push,并确保你的应用在受支持的平台上能够在 debug 和 release 模式下都成功编译并运行。
4.
项目中必须安装并配置对 Expo modules(通过 expo 包)的支持。更多信息请参阅 将 Expo 工具集成到现有原生应用中。
5.
你的 metro.config.js 必须扩展 expo/metro-config。
6.
你的 babel.config.js 必须扩展 babel-preset-expo。
7.
npx expo export 能成功运行如果你的项目支持 Android,则命令 npx expo export -p android 必须能在项目中成功运行;如果支持 iOS,则 npx expo export -p ios 也必须能成功运行。
安装和基础配置
按照 Get started with EAS Update 指南中的第 1、2、3、4 步操作。
完成后,你将已经安装并通过 eas-cli 完成身份验证,已将 expo-updates 安装到项目中,已初始化关联的 EAS 项目,并为原生项目添加了基础配置。
取消自动设置
下一步是禁用 expo-updates 的默认行为,使其不再以适用于 greenfield React Native 项目的方式自动完成自身设置。
在 Android 上禁用自动设置
修改 android/gradle.properties,设置用于禁用自动更新初始化的属性,如下例所示:
在 iOS 上禁用自动设置
通过向 CocoaPods 安装传入环境变量来禁用自动更新初始化。
设置 React Native 应用以在加载发布版 bundle 时使用 expo-updates
下一步是将 expo-updates 集成到你的 Android 和 iOS 项目中,这样你的应用在 release 构建中会使用 expo-updates 作为 JavaScript 代码来源。
将 expo-updates 集成到 React Native 打包流程中
-
确保你的 Metro 配置扩展了 Expo 配置,如下例所示:
metro.config.js -
如果你使用自定义入口点,请务必在那里包含 Expo 初始化。这可确保 Expo 库(包括
expo-updates)都能正确初始化。下面有两个示例:First Custom Entry Point file exampleSecond custom entry point file example
在 Android 上集成 expo-updates
以下说明假设你的应用使用 Kotlin 编写。你需要更新两个文件:MainApplication.kt 和 MainActivity.kt。
MainApplication 更改
打开 android/app/src/main/java/com/<your-app-name>/MainApplication.kt 并按以下步骤操作。
- 你的 Application 类应实现
ReactApplication。 - 重写
reactHost,使用ExpoReactHostFactory.getDefaultReactHost()。这会以正确的 expo-updates 集成来设置 React host。 - 在
onCreate()中调用loadReactNative()和ApplicationLifecycleDispatcher.onApplicationCreate()来初始化 Expo modules。
MainActivity 更改
打开 android/app/src/main/java/com/<your-app-name>/MainActivity.kt 并按以下步骤操作。
- 你的 React Native Activity 应继承
com.facebook.react.ReactActivity。 - 重写
getMainComponentName(),返回你在上面 JS 入口点中注册的应用名称。 - 按如下方式使用
ReactActivityDelegateWrapper重写createReactActivityDelegate()。
在 iOS 上集成 expo-updates
以下说明假设你的应用使用 Swift 编写,并且有一个或多个带有自定义 UIViewController 的原生界面。我们将添加一个自定义视图控制器来渲染你的 React Native 应用。
AppDelegate 更改
- 修改 AppDelegate.swift,使其继承
ExpoAppDelegate。 - 如果你还没有这样做,请添加一个公共方法来获取正在运行的
AppDelegate实例,以便你的自定义视图控制器稍后可以访问它。 - 添加对
expo-updates单例AppController类的引用,它负责管理 iOS 上的更新系统。 - 添加一个新类
CustomReactNativeFactoryDelegate,使其继承ExpoReactNativeFactoryDelegate,并重写bundleUrl()方法,以便在更新系统运行时返回正确的更新 bundle URL。 didFinishLaunchingWithOptions()方法需要执行两个步骤:- 使用上面创建的
CustomReactNativeFactoryDelegate初始化ExpoReactNativeFactory。之后,它将用于创建 React Native 根视图。 - 调用
AppController.initializeWithoutStarting()。这会创建控制器实例,但会将更新启动流程的其余部分延后到真正需要时再执行。
- 使用上面创建的
实现自定义视图控制器
- 视图控制器应实现更新协议
AppControllerDelegate。 - 视图控制器初始化应当:
- 设置 app delegate 的 updates controller 实例,以便上面的
bundleURL()方法能够正确用于更新。 - 将
AppController的 delegate 设置为该视图控制器实例 - 启动
AppController
- 设置 app delegate 的 updates controller 实例,以便上面的
- 最后,视图控制器必须实现
AppControllerDelegate协议中的一个方法,appController(_ appController: AppControllerInterface, didStartWithSuccess success: Bool)。当更新系统完全初始化完成,并且最新更新(或内置 bundle)已准备好渲染时,会调用此方法。- 使用 app delegate 创建的
ExpoReactNativeFactory创建 React Native 根视图。传入的应用名称必须与上面的 JS 入口点中注册的应用名称一致。 - 将此根视图添加到视图控制器中。
- 使用 app delegate 创建的
AppDelegate 更改
- 修改 AppDelegate.swift,使其继承
EXAppDelegateWrapper。 - 如果你还没有这样做,请添加一个公共方法来获取正在运行的
AppDelegate实例,以便你的自定义视图控制器稍后可以访问它。 - 添加对
expo-updates单例AppController类的引用,它负责管理 iOS 上的更新系统。 - 重写
bundleUrl()方法,以便在更新系统运行时返回正确的更新 bundle URL。 didFinishLaunchingWithOptions()方法需要执行两个步骤:- 初始化稍后用于创建 React Native 根视图的根视图工厂。
- 调用
AppController.initializeWithoutStarting()。这会创建控制器实例,但会将更新启动流程的其余部分延后到需要时再执行。
实现自定义视图控制器
- 视图控制器应实现更新协议
AppControllerDelegate。 - 视图控制器初始化应当:
- 设置 app delegate 的 updates controller 实例,以便上面的
bundleURL()方法能够正确用于更新。 - 将
AppController的 delegate 设置为该视图控制器实例 - 启动
AppController
- 设置 app delegate 的 updates controller 实例,以便上面的
- 最后,视图控制器必须实现
AppControllerDelegate协议中的一个方法,appController(_ appController: AppControllerInterface, didStartWithSuccess success: Bool)。当更新系统完全初始化完成,并且最新更新(或内置 bundle)已准备好渲染时,会调用此方法。- 使用 app delegate 创建的根视图工厂创建 React Native 根视图。传入的应用名称必须与上面的 JS 入口点中注册的应用名称一致。
- 将此根视图添加到视图控制器中。
常见问题
将其添加到我的应用需要多长时间?
假设你使用的是 Expo SDK 支持的最新版本 React Native,并且你对原生项目中的 React Native 集成很熟悉,那么你很可能可以在与集成 CodePush 或 Sentry 等工具相近的时间内集成 EAS Update。
最重要的因素是你的应用所使用的 React Native 版本。如果你的应用使用的是比 Expo SDK 当前支持的最新版本更旧的版本(如本指南顶部所引用的版本),那么你应该先升级到该版本,而所需时间将高度取决于应用的规模和复杂度,以及负责该工作的团队的技能和经验水平。
我正在从 CodePush 迁移,我还需要知道什么?
要了解更多信息,请参阅从 CodePush 迁移指南。