This documentation is available as Markdown for AI agents and LLMs. See the full Markdown index or append .md to any documentation URL.
This is documentation for the next SDK version. For up-to-date documentation, see the latest version (SDK 57).
Expo 更新
一个让你的应用能够管理应用代码远程更新的库。
expo-updates 是一个可让你的应用远程管理应用代码更新的库。它会与配置的远程更新服务通信,以获取有关可用更新的信息。
安装
expo-updates 库可以通过 EAS Update 自动配置。EAS Update 是一项托管服务,用于管理更新并将其提供给你的应用。要开始使用 EAS Update,请按照开始使用指南中的说明进行操作。
此外,如果你需要使用不同的远程更新服务,或仅在原生文件中指定配置,也可以手动配置 expo-updates 库。
手动安装、配置和自定义远程更新服务
如果你是在现有 React Native 项目中安装此库,或者是在手动配置原生代码的通用应用中安装,请遵循这些安装说明。
如果使用应用配置进行配置,则可以通过至少设置以下应用配置属性来配置此库:
updates.url:实现 Expo Updates protocol 的远程服务 URLruntimeVersion:一个运行时版本
远程服务必须实现 Expo Updates protocol。EAS Update 就是这样一种服务,但也可以将此库与自定义服务器一起使用。
自定义服务器及使用该服务器的应用示例实现。
配置
有一些构建时配置选项用于控制此库的行为。对于大多数应用,这些配置值都在应用配置的 updates 属性下设置。
updates.maxUpdatesToKeep 控制保留的更新数量,包括当前正在运行的更新。例如,将其设为 3,会保留正在运行的更新和最多两个较旧的更新。符合清单筛选条件的更新优先保留,并从最新的更新开始保留。
此值控制与正在运行的更新一起保留的较旧更新数量。清理时会保留其他作用域的更新,以及提交时间与正在运行的更新相同或更晚的更新,因此缓存中的更新数量可能超过此值。
两个核心必需配置项是:
updates.url:此库获取远程更新的 URLruntimeVersion:一个运行时版本
按照 EAS Update 的开始使用指南操作时,这些都会自动配置。
运行时版本
每次为你的应用构建二进制文件时,其中都会包含构建时存在的原生代码和配置。这个独特组合会以一个称为运行时版本的字符串表示。远程更新会面向某个运行时版本,这表示只有运行时版本匹配的二进制文件才能加载该远程更新。
使用运行时版本策略自动配置
运行时版本策略会根据项目中已存在的其他信息推导运行时版本。可以在 runtimeVersion 配置字段中按如下方式设置:
{ "expo": { "runtimeVersion": { "policy": "<policy_name>" } } }
可用的策略类型:
appVersion
"appVersion" 策略适用于希望基于应用版本定义运行时兼容性的项目。
例如,在一个应用配置中包含以下内容的项目里:
{ "expo": { "runtimeVersion": { "policy": "appVersion" }, "version": "1.0.0", "ios": { "buildNumber": "1" }, "android": { "versionCode": 1 } } }
"appVersion" 策略会将运行时版本设置为项目当前的 "version" 属性。在这种情况下,Android 和 iOS 构建以及任何更新的运行时版本都将是 "1.0.0"。
此策略非常适合包含自定义原生代码,并且在每次公开发布后都会更新 "version" 字段的项目。要提交应用,应用商店要求每个提交的构建都具有更新后的原生版本号,因此如果你希望确保安装到用户设备上的每个版本都拥有不同的运行时版本,此策略会很方便。
使用此策略时,你需要在每次公开发布时手动更新应用配置中的 "version" 字段,但对于 Play Store 的 Internal Test Track 和 App Store 的 TestFlight 上传,你可以依赖 eas.json 中的 "autoIncrement" 选项来替你管理版本。
nativeVersion
"nativeVersion" 策略适用于希望基于项目当前的 "version" 和 "versionCode"(Android)或 "buildNumber"(iOS)属性定义运行时兼容性的项目。
例如,在一个应用配置中包含以下内容的项目里:
{ "expo": { "runtimeVersion": { "policy": "nativeVersion" }, "version": "1.0.0", "ios": { "buildNumber": "1" }, "android": { "versionCode": 1 } } }
Android 和 iOS 构建以及任何更新的运行时版本都将是 "[version]([buildNumber|versionCode])" 的组合,在此例中将是 "1.0.0(1)"。
此策略非常适合包含自定义原生代码、并且在每次构建时都会更新原生版本号(iOS 的 "buildNumber" 和 Android 的 "versionCode")的项目。要提交应用,应用商店要求每个提交的构建都具有更新后的原生版本号,因此如果你希望确保上传到 Play Store 的 Internal Test Track 以及 App Store 的 TestFlight 分发工具的每个应用都拥有不同的 runtimeVersion,此策略会很方便。
需要注意的是,此策略要求在每次构建之间手动管理原生版本号。
此外,如果你为 Android 和 iOS 选择不同的原生版本,那么最终会得到具有各自独立运行时版本的构建和更新。
fingerprint
"fingerprint" 运行时版本策略会自动为你计算运行时版本,包括 SDK 升级或添加自定义原生代码等更改。
{ "expo": { "runtimeVersion": { "policy": "fingerprint" } } }
此策略适用于包含或不包含自定义原生代码的项目。它通过使用 @expo/fingerprint 包,在构建和更新期间计算项目的哈希值,以确定构建与更新的兼容性(也称为运行时)。
原生配置与覆盖
如果你的项目没有使用 Continuous Native Generation,这些配置值也可以在应用的原生配置文件中设置,或在原生代码初始化期间被覆盖。
原生配置说明
在 Android 上,这些选项会作为 meta-data 标签设置在 AndroidManifest.xml 文件中(如果使用自动设置,则位于安装过程中添加的标签旁边)。你也可以在运行时使用 UpdatesController.overrideConfiguration() 来设置或覆盖它们。
在 iOS 上,这些属性会作为键设置在 Expo.plist 文件中。你也可以通过调用 AppController.overrideConfiguration 在运行时设置或覆盖它们。
用法
默认情况下,expo-updates 会在应用启动时检查更新。如果有可用更新,它会下载该更新,并在应用下次重启时应用。你可以使用上面的 checkAutomatically 和 fallbackToCacheTimeout 配置选项来调整这种启动行为。
此库还提供了多种常量,用于检查当前更新;以及一些函数,用于在应用代码中(启动后)自定义更新行为。例如,一种常见的替代用法是在应用启动后手动检查更新,而不是在启动时执行默认检查。
示例:手动检查更新
你可以通过以下步骤将应用配置为手动检查更新:
-
将
checkAutomatically配置值设置为ON_ERROR_RECOVERY或NEVER,以禁用此库默认的启动行为。 -
添加以下代码以检查可用更新、下载它们并重新加载:
App.js
测试
本库中的大多数方法和常量只能在发布构建中使用或测试。在调试构建中,默认行为是始终从开发服务器加载最新的 JavaScript。可以构建一个与发布构建具有相同更新行为的调试版本。这样的应用不会从你的开发服务器加载最新的 JavaScript,而是像发布构建一样加载已发布的更新。这对于在未连接开发服务器时调试应用行为可能很有用。
要在开发构建中测试更新内容,请运行 eas update,然后在你的开发构建中浏览该更新。请注意,这只是模拟更新在你的应用中的呈现效果,并且在开发构建运行时,大多数 Updates API 都不可用。
要在发布构建中测试更新,你可以创建一个 .apk 或一个模拟器构建,或者使用 npx expo run:android --variant release 和 npx expo run:ios --configuration Release 在本地制作发布构建(你无需将此构建提交到商店即可测试)。完整的 Updates API 在发布构建中可用。
要在 Expo Go 中测试更新内容,请运行 eas update,然后在 Expo Go 中浏览该更新。请注意,这只是模拟更新在你的应用中的呈现效果,并且在 Expo Go 运行时,大多数 Updates API 都不可用。另请注意,仅支持使用与 Expo Go 兼容的库的更新。
API
import * as Updates from 'expo-updates';
Constants
Type: string | null
The channel name of the current build, if configured for use with EAS Update. null otherwise.
Expo Go and development builds are not set to a specific channel and can run any updates compatible with their native runtime. Therefore, this value will always be null when running an update on Expo Go or a development build.
Type: UpdatesCheckAutomaticallyValue | null
Determines if and when expo-updates checks for and downloads updates automatically on startup.
Type: Date | null
If expo-updates is enabled, this is a Date object representing the creation time of the update that's currently running (whether it was embedded or downloaded at runtime).
In development mode, or any other environment in which expo-updates is disabled, this value is
null.
Type: string | null
If isEmergencyLaunch is set to true, this will contain a string error message describing
what failed during initialization.
Type: boolean
This will be true if the currently running update is the one embedded in the build, and not one downloaded from the updates server.
Type: boolean
expo-updates does its very best to always launch monotonically newer versions of your app so
you don't need to worry about backwards compatibility when you put out an update. In very rare
cases, it's possible that expo-updates may need to fall back to the update that's embedded in
the app binary, even after newer updates have been downloaded and run (an "emergency launch").
This boolean will be true if the app is launching under this fallback mechanism and false
otherwise. If you are concerned about backwards compatibility of future updates to your app, you
can use this constant to provide special behavior for this rare case.
Type: boolean
Whether expo-updates is enabled. This may be false in a variety of cases including:
- enabled set to false in configuration
- missing or invalid URL in configuration
- missing runtime version or SDK version in configuration
- error accessing storage on device during initialization
When false, the embedded update is loaded.
If expo-updates is enabled, this is the
manifest object for the update
that's currently running.
In development mode, or any other environment in which expo-updates is disabled, this object is
empty.
Type: string | null
The UUID that uniquely identifies the currently running update. The
UUID is represented in its canonical string form and will always use lowercase letters.
This value is null when running in a local development environment or any other environment where expo-updates is disabled.
Example
"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
Hooks
Hook that obtains information on available updates and on the currently running update.
UseUpdatesReturnTypeExample
Classes
Type: Class extends NativeModule<UpdatesEvents> implements UpdatesModuleInterface
ExpoUpdatesModule Properties
() => Promise<void>(requestHeaders: Record<string, string> | null) => void(configOverride: {
requestHeaders: Record<string, string> | null,
updateUrl: string
} | null) => void(options?: ReloadScreenOptions | null) => Promise<void>Methods
Checks the server to see if a newly deployed update to your project is available. Does not actually download the update. This method cannot be used in development mode, and the returned promise will be rejected if you try to do so.
Checking for an update uses a device's bandwidth and battery life like any network call. Additionally, updates served by Expo may be rate limited. A good rule of thumb to check for updates judiciously is to check when the user launches or foregrounds the app. Avoid polling for updates in a frequent loop.
Promise<UpdateCheckResult>A promise that fulfills with an UpdateCheckResult object.
The promise rejects in Expo Go or if the app is in development mode, or if there is an unexpected error or
timeout communicating with the server. It also rejects when expo-updates is not enabled.
Clears existing expo-updates log entries.
For now, this operation does nothing on the client. Once log persistence has been implemented, this operation will actually remove existing logs.
Promise<void>A promise that fulfills if the clear operation was successful.
The promise rejects if there is an unexpected error in clearing the logs.
Downloads the most recently deployed update to your project from server to the device's local storage. This method cannot be used in development mode, and the returned promise will be rejected if you try to do so.
Note:
reloadAsync()can be called after promise resolution to reload the app using the most recently downloaded version. Otherwise, the update will be applied on the next app cold start.
Promise<UpdateFetchResult>A promise that fulfills with an UpdateFetchResult object.
The promise rejects in Expo Go or if the app is in development mode, or if there is an unexpected error or
timeout communicating with the server. It also rejects when expo-updates is not enabled.
Retrieves the current extra params.
This method cannot be used in Expo Go or development mode. It also rejects when expo-updates is not enabled.
Promise<Record<string, string>>Retrieves the most recent expo-updates log entries.
Promise<UpdatesLogEntry[]>A promise that fulfills with an array of UpdatesLogEntry objects;
The promise rejects if there is an unexpected error in retrieving the logs.
Instructs the app to reload using the most recently downloaded version. This is useful for
triggering a newly downloaded update to launch without the user needing to manually restart the
app.
Unlike Expo.reloadAppAsync() provided by the expo package,
this function not only reloads the app but also changes the loaded JavaScript bundle to that of the most recently downloaded update.
It is not recommended to place any meaningful logic after a call to await Updates.reloadAsync(). This is because the promise is resolved after verifying that the app can
be reloaded, and immediately before posting an asynchronous task to the main thread to actually
reload the app. It is unsafe to make any assumptions about whether any more JS code will be
executed after the Updates.reloadAsync method call resolves, since that depends on the OS and
the state of the native module and main threads.
This method cannot be used in Expo Go or development mode, and the returned promise will be rejected if you
try to do so. It also rejects when expo-updates is not enabled.
Promise<void>A promise that fulfills right before the reload instruction is sent to the JS runtime, or
rejects if it cannot find a reference to the JS runtime. If the promise is rejected in production
mode, it most likely means you have installed the module incorrectly. Double check you've
followed the installation instructions. In particular, on iOS ensure that you set the bridge
property on EXUpdatesAppController with a pointer to the RCTBridge you want to reload, and on
Android ensure you either call UpdatesController.initialize with the instance of
ReactApplication you want to reload, or call UpdatesController.setReactNativeHost with the
proper instance of ReactNativeHost.
Sets an extra param if value is non-null, otherwise unsets the param.
Extra params are sent as an Expo Structured Field Value Dictionary
in the Expo-Extra-Params header of update requests. A compliant update server may use these params when selecting an update to serve.
This method cannot be used in Expo Go or development mode. It also rejects when expo-updates is not enabled.
Promise<void>Overrides updates request headers in runtime from build time. This method allows you to load specific updates with custom request headers. Use this method at your own risk, as it may cause unexpected behavior. Learn more about use cases and limitations.
voidOverrides updates URL and request headers in runtime from build time.
This method allows you to load specific updates from a URL that you provide.
Use this method at your own risk, as it may cause unexpected behavior.
Because of the risk, this method requires disableAntiBrickingMeasures to be set to true in the app.json file.
Learn more about use cases and limitations.
voidInterfaces
Configuration options for customizing the reload screen appearance.
Common interface for all native module implementations (android, ios, web).
Types
Structure encapsulating information on the currently running app (either the embedded bundle or a downloaded update).
Literal type: union
Acceptable values are: ExpoUpdatesManifest | EmbeddedManifest
Literal type: union
The result of checking for a new update.
Acceptable values are: UpdateCheckResultRollBack | UpdateCheckResultAvailable | UpdateCheckResultNotAvailable
The update check result when a new update is found on the server.
The update check result when a rollback directive is received.
Literal type: union
The result of fetching a new update.
Acceptable values are: UpdateFetchResultSuccess | UpdateFetchResultFailure | UpdateFetchResultRollBackToEmbedded
The roll back to embedded result of fetching a new update.
Literal type: union
Combined structure representing any type of update.
Acceptable values are: UpdateInfoNew | UpdateInfoRollback
Literal type: string
Acceptable values are: 'ALWAYS' | 'ERROR_RECOVERY_ONLY' | 'NEVER' | 'WIFI_ONLY'
An object representing a single log entry from expo-updates logging on the client.
Enums
UpdateCheckResultNotAvailableReason.NO_UPDATE_AVAILABLE_ON_SERVER = "noUpdateAvailableOnServer"No update manifest or rollback directive received from the update server.
UpdateCheckResultNotAvailableReason.ROLLBACK_NO_EMBEDDED = "rollbackNoEmbeddedConfiguration"A rollback directive was received from the update server, but this app has no embedded update.
UpdateCheckResultNotAvailableReason.ROLLBACK_REJECTED_BY_SELECTION_POLICY = "rollbackRejectedBySelectionPolicy"A rollback directive was received from the update server, but the directive does not pass the configured selection policy.
UpdateCheckResultNotAvailableReason.UPDATE_PREVIOUSLY_FAILED = "updatePreviouslyFailed"An update manifest was received from the update server, but the update has been previously launched on this device and never successfully launched.
The different possible types of updates.
Currently, the only supported type is UpdateInfoType.NEW, indicating a new update that can be downloaded and launched
on the device.
In the future, other types of updates may be added to this list.
UpdateInfoType.NEW = "new"This is the type for new updates found on or downloaded from the update server, that are launchable on the device.
The possible settings that determine if expo-updates will check for updates on app startup.
By default, Expo will check for updates every time the app is loaded.
Set this to ON_ERROR_RECOVERY to disable automatic checking unless recovering from an error.
Set this to NEVER to completely disable automatic checking.
UpdatesCheckAutomaticallyValue.NEVER = "NEVER"Automatic update checks are off, and update checks must be done through the JS API.
UpdatesCheckAutomaticallyValue.ON_ERROR_RECOVERY = "ON_ERROR_RECOVERY"Only checks for updates when the app starts up after an error recovery.
UpdatesCheckAutomaticallyValue.ON_LOAD = "ON_LOAD"Checks for updates whenever the app is loaded. This is the default setting.
The possible code values for expo-updates log entries
UpdatesLogEntryCode.UPDATE_ASSETS_NOT_AVAILABLE = "UpdateAssetsNotAvailable"UpdatesLogEntryCode.UPDATE_HAS_INVALID_SIGNATURE = "UpdateHasInvalidSignature"The possible log levels for expo-updates log entries