expo-updates-interface 55.1.2 → 55.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -10,6 +10,12 @@
10
10
 
11
11
  ### 💡 Others
12
12
 
13
+ ## 55.1.3 — 2026-02-25
14
+
15
+ ### ⚠️ Notices
16
+
17
+ - Documentation for new native interface. ([#43230](https://github.com/expo/expo/pull/43230) by [@douglowder](https://github.com/douglowder))
18
+
13
19
  ## 55.1.2 — 2026-02-16
14
20
 
15
21
  ### 🎉 New features
package/README.md CHANGED
@@ -1,13 +1,236 @@
1
1
  # expo-updates-interface
2
2
 
3
- Native interface for modules that optionally depend on expo-updates, e.g. expo-dev-launcher.
3
+ Native interface for modules that optionally depend on expo-updates. This package provides a unified native API (iOS and Android) for querying the state of the updates system and subscribing to state machine transitions, without requiring a direct dependency on `expo-updates`.
4
+
5
+ ## Overview
6
+
7
+ `expo-updates-interface` defines two levels of interface:
8
+
9
+ - **`UpdatesInterface`** -- implemented by all updates controllers (enabled, disabled, and dev-launcher). Provides read-only properties describing the running update and a method to subscribe to state machine changes.
10
+ - **`UpdatesDevLauncherInterface`** -- extends `UpdatesInterface` with additional methods used exclusively by `expo-dev-launcher` to fetch updates and manage the update lifecycle.
11
+
12
+ A singleton **`UpdatesControllerRegistry`** provides access to the active controller that implements one or both of the above interfaces.
4
13
 
5
14
  ## API documentation
6
15
 
16
+ ### UpdatesControllerRegistry
17
+
18
+ The registry provides the active updates controller as a weak reference, in the `controller` property. The reference will be null when `expo-updates` is not installed and compiled into the app. If `expo-updates` is present, the property is set automatically at startup.
19
+
20
+ | Platform | Access |
21
+ | ----------- | ----------------------------------------------------- |
22
+ | **iOS** | `UpdatesControllerRegistry.sharedInstance.controller` |
23
+ | **Android** | `UpdatesControllerRegistry.controller?.get()` |
24
+
25
+ ### UpdatesInterface
26
+
27
+ All updates controllers implement this interface. It is available whether updates is enabled, disabled, or running under the dev client.
28
+
29
+ #### Properties
30
+
31
+ | Property | Type | Description |
32
+ | ----------------------------------------- | ------------------ | ------------------------------------------------------------------------------------------------------------- |
33
+ | `isEnabled` | `Bool` / `Boolean` | Whether the updates system is enabled. Defaults to `false` when updates is disabled. |
34
+ | `runtimeVersion` | `String?` | The runtime version of the running app. Set when updates is enabled or the dev client is running. |
35
+ | `updateURL` (iOS) / `updateUrl` (Android) | `URL?` / `Uri?` | The update URL configured for this app. Set when updates is enabled or the dev client is running. |
36
+ | `launchedUpdateId` | `UUID?` | The ID of the currently running update. Only set when updates is enabled. |
37
+ | `embeddedUpdateId` | `UUID?` | The ID of the update embedded in the app binary. Only set when updates is enabled. |
38
+ | `launchAssetPath` | `String?` | The local file path of the launch asset (JS bundle) for the running update. Only set when updates is enabled. |
39
+
40
+ #### Methods
41
+
42
+ ##### `subscribeToUpdatesStateChanges`
43
+
44
+ Registers a listener that will be called on updates state machine transitions. Returns a subscription object that can be used to unsubscribe.
45
+
46
+ **iOS:**
47
+
48
+ ```swift
49
+ func subscribeToUpdatesStateChanges(_ listener: any UpdatesStateChangeListener) -> UpdatesStateChangeSubscription
50
+ ```
51
+
52
+ **Android (Kotlin):**
53
+
54
+ ```kotlin
55
+ fun subscribeToUpdatesStateChanges(listener: UpdatesStateChangeListener): UpdatesStateChangeSubscription
56
+ ```
57
+
58
+ ### UpdatesStateChangeListener
59
+
60
+ A listener protocol/interface that receives state machine transition events.
61
+
62
+ **iOS:**
63
+
64
+ ```swift
65
+ public protocol UpdatesStateChangeListener {
66
+ func updatesStateDidChange(_ event: [String: Any])
67
+ }
68
+ ```
69
+
70
+ **Android (Kotlin):**
71
+
72
+ ```kotlin
73
+ interface UpdatesStateChangeListener {
74
+ fun updatesStateDidChange(event: Map<String, Any>)
75
+ }
76
+ ```
77
+
78
+ The `event` dictionary contains information about the state transition, matching the structure of the updates state machine events exposed by the `expo-updates` JS API.
79
+
80
+ ### UpdatesStateChangeSubscription
81
+
82
+ Returned by `subscribeToUpdatesStateChanges`. Call `remove()` to unsubscribe and stop receiving state change events.
83
+
84
+ **iOS:**
85
+
86
+ ```swift
87
+ public protocol UpdatesStateChangeSubscription {
88
+ func remove()
89
+ }
90
+ ```
91
+
92
+ **Android (Kotlin):**
93
+
94
+ ```kotlin
95
+ interface UpdatesStateChangeSubscription {
96
+ fun remove()
97
+ }
98
+ ```
99
+
100
+ ### UpdatesDevLauncherInterface
101
+
102
+ Extends `UpdatesInterface` with methods used by `expo-dev-launcher` to fetch and manage updates. This interface is only implemented by the dev-launcher updates controller.
103
+
104
+ See the source files for the full method signatures:
105
+
106
+ - **iOS:** [`UpdatesInterface.swift`](ios/EXUpdatesInterface/UpdatesInterface.swift)
107
+ - **Android:** [`UpdatesInterface.kt`](android/src/main/java/expo/modules/updatesinterface/UpdatesInterface.kt)
108
+
109
+ ## Usage example
110
+
111
+ ### Reading update information (Kotlin)
112
+
113
+ ```kotlin
114
+ import expo.modules.updatesinterface.UpdatesControllerRegistry
115
+
116
+ val controller = UpdatesControllerRegistry.controller?.get()
117
+ if (controller != null && controller.isEnabled) {
118
+ val updateId = controller.launchedUpdateId
119
+ val runtimeVersion = controller.runtimeVersion
120
+ // ...
121
+ }
122
+ ```
123
+
124
+ ### Reading update information (Swift)
125
+
126
+ ```swift
127
+ import EXUpdatesInterface
128
+
129
+ if let controller = UpdatesControllerRegistry.sharedInstance.controller,
130
+ controller.isEnabled {
131
+ let updateId = controller.launchedUpdateId
132
+ let runtimeVersion = controller.runtimeVersion
133
+ // ...
134
+ }
135
+ ```
136
+
137
+ ### Subscribing to state changes (Kotlin)
138
+
139
+ ```kotlin
140
+ import expo.modules.updatesinterface.UpdatesControllerRegistry
141
+ import expo.modules.updatesinterface.UpdatesStateChangeListener
142
+ import expo.modules.updatesinterface.UpdatesStateChangeSubscription
143
+
144
+ val controller = UpdatesControllerRegistry.controller?.get() ?: return
145
+
146
+ val subscription = controller.subscribeToUpdatesStateChanges(object : UpdatesStateChangeListener {
147
+ override fun updatesStateDidChange(event: Map<String, Any>) {
148
+ // Handle state change event
149
+ }
150
+ })
151
+
152
+ // Later, to unsubscribe:
153
+ subscription.remove()
154
+ ```
155
+
156
+ ### Subscribing to state changes (Swift)
157
+
158
+ ```swift
159
+ import EXUpdatesInterface
160
+
161
+ class MyListener: NSObject, UpdatesStateChangeListener {
162
+ func updatesStateDidChange(_ event: [String: Any]) {
163
+ // Handle state change event
164
+ }
165
+ }
166
+
167
+ let listener = MyListener()
168
+ if let controller = UpdatesControllerRegistry.sharedInstance.controller {
169
+ let subscription = controller.subscribeToUpdatesStateChanges(listener)
170
+
171
+ // Later, to unsubscribe:
172
+ subscription.remove()
173
+ }
174
+ ```
175
+
176
+ ## Installation in an Expo native module
177
+
178
+ - The `expo-updates-interface` package should be added to the module's NPM dependencies. (The `expo-updates` package does not need to be added.)
179
+ - The module's iOS podspec should have "EXUpdatesInterface" added to the pod dependencies, as in this example:
180
+
181
+ ```ruby
182
+ Pod::Spec.new do |s|
183
+ s.name = 'InterfaceDemo'
184
+ s.version = '1.0.0'
185
+ s.platforms = {
186
+ :ios => '15.1',
187
+ :tvos => '15.1'
188
+ }
189
+ s.static_framework = true
190
+
191
+ s.dependency 'ExpoModulesCore'
192
+ s.dependency 'EXUpdatesInterface'
193
+
194
+ # Swift/Objective-C compatibility
195
+ s.pod_target_xcconfig = {
196
+ 'DEFINES_MODULE' => 'YES',
197
+ }
198
+
199
+ s.source_files = "**/*.{h,m,mm,swift,hpp,cpp}"
200
+ end
201
+ ```
202
+
203
+ - The module's Android `build.gradle` should have this package added as a dependency, as in this example:
204
+
205
+ ```gradle
206
+ android {
207
+ namespace "expo.modules.interfacedemo"
208
+ defaultConfig {
209
+ versionCode 1
210
+ versionName "0.7.6"
211
+ }
212
+ lintOptions {
213
+ abortOnError false
214
+ }
215
+ }
216
+
217
+ dependencies {
218
+ implementation project(':expo-updates-interface')
219
+ }
220
+ ```
221
+
7
222
  ## Installation in managed Expo projects
8
223
 
224
+ This package is included as a dependency of `expo-updates` and `expo-dev-client`. No separate installation is needed.
225
+
9
226
  ## Installation in bare React Native projects
10
227
 
228
+ This package is included as a dependency of `expo-updates` and `expo-dev-client`. If you need to install it separately:
229
+
230
+ ```sh
231
+ npx expo install expo-updates-interface
232
+ ```
233
+
11
234
  ## Contributing
12
235
 
13
236
  Contributions are very welcome! Please refer to guidelines described in the [contributing guide](https://github.com/expo/expo#contributing).
@@ -4,7 +4,7 @@ plugins {
4
4
  }
5
5
 
6
6
  group = 'host.exp.exponent'
7
- version = '55.1.2'
7
+ version = '55.1.3'
8
8
 
9
9
  expoModule {
10
10
  canBePublished false
@@ -14,6 +14,6 @@ android {
14
14
  namespace "expo.modules.updatesinterface"
15
15
  defaultConfig {
16
16
  versionCode 1
17
- versionName '55.1.2'
17
+ versionName '55.1.3'
18
18
  }
19
19
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "expo-updates-interface",
3
- "version": "55.1.2",
3
+ "version": "55.1.3",
4
4
  "description": "Native interface for modules that optionally depend on expo-updates, e.g. expo-dev-launcher.",
5
5
  "main": "index.js",
6
6
  "keywords": [
@@ -23,5 +23,5 @@
23
23
  "peerDependencies": {
24
24
  "expo": "*"
25
25
  },
26
- "gitHead": "928cc951854450f3c72e00e8e420e567fabd1f8c"
26
+ "gitHead": "b183e5cbd95eb6ee54a878291c7077d8d63e4850"
27
27
  }