expo-updates 0.27.3 → 0.27.4
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 +6 -0
- package/android/build.gradle +7 -2
- package/android/src/main/java/expo/modules/updates/IUpdatesController.kt +1 -1
- package/android/src/main/java/expo/modules/updates/UpdatesController.kt +1 -1
- package/android/src/main/java/expo/modules/updates/UpdatesPackage.kt +9 -6
- package/e2e/fixtures/project_files/eas.json +0 -6
- package/e2e/setup/project.ts +13 -2
- package/expo-updates-gradle-plugin/src/main/kotlin/expo/modules/updates/ExpoUpdatesPlugin.kt +9 -1
- package/ios/EXUpdates/ReactDelegateHandler/ExpoUpdatesReactDelegateHandler.swift +7 -0
- package/ios/EXUpdates/UpdatesUtils.swift +9 -1
- package/ios/EXUpdates.podspec +30 -9
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -10,6 +10,12 @@
|
|
|
10
10
|
|
|
11
11
|
### 💡 Others
|
|
12
12
|
|
|
13
|
+
## 0.27.4 — 2025-03-18
|
|
14
|
+
|
|
15
|
+
### 🎉 New features
|
|
16
|
+
|
|
17
|
+
- Support brownfield apps with EX_UPDATES_CUSTOM_INIT flag. ([#35391](https://github.com/expo/expo/pull/35391) by [@douglowder](https://github.com/douglowder))
|
|
18
|
+
|
|
13
19
|
## 0.27.3 — 2025-03-11
|
|
14
20
|
|
|
15
21
|
### 🐛 Bug fixes
|
package/android/build.gradle
CHANGED
|
@@ -16,7 +16,7 @@ apply plugin: 'com.android.library'
|
|
|
16
16
|
apply plugin: 'com.google.devtools.ksp'
|
|
17
17
|
|
|
18
18
|
group = 'host.exp.exponent'
|
|
19
|
-
version = '0.27.
|
|
19
|
+
version = '0.27.4'
|
|
20
20
|
|
|
21
21
|
def expoModulesCorePlugin = new File(project(":expo-modules-core").projectDir.absolutePath, "ExpoModulesCorePlugin.gradle")
|
|
22
22
|
apply from: expoModulesCorePlugin
|
|
@@ -49,6 +49,10 @@ def getBoolStringFromPropOrEnv(String name, Boolean defaultValue) {
|
|
|
49
49
|
// debug builds. (default false)
|
|
50
50
|
def exUpdatesNativeDebug = getBoolStringFromPropOrEnv("EX_UPDATES_NATIVE_DEBUG", false)
|
|
51
51
|
|
|
52
|
+
// If true, app is using custom code to initialize expo-updates, so default initialization code
|
|
53
|
+
// will be disabled.
|
|
54
|
+
def exUpdatesCustomInit = getBoolStringFromPropOrEnv("EX_UPDATES_CUSTOM_INIT", false)
|
|
55
|
+
|
|
52
56
|
// If true, code will run that delays app loading until updates is initialized, to prevent ANR issues.
|
|
53
57
|
// (default true)
|
|
54
58
|
def exUpdatesAndroidDelayLoadApp = getBoolStringFromPropOrEnv("EX_UPDATES_ANDROID_DELAY_LOAD_APP", true)
|
|
@@ -63,11 +67,12 @@ android {
|
|
|
63
67
|
namespace "expo.modules.updates"
|
|
64
68
|
defaultConfig {
|
|
65
69
|
versionCode 31
|
|
66
|
-
versionName '0.27.
|
|
70
|
+
versionName '0.27.4'
|
|
67
71
|
consumerProguardFiles("proguard-rules.pro")
|
|
68
72
|
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
|
69
73
|
|
|
70
74
|
buildConfigField("boolean", "EX_UPDATES_NATIVE_DEBUG", exUpdatesNativeDebug)
|
|
75
|
+
buildConfigField("boolean", "EX_UPDATES_CUSTOM_INIT", exUpdatesCustomInit)
|
|
71
76
|
buildConfigField("boolean", "EX_UPDATES_ANDROID_DELAY_LOAD_APP", exUpdatesAndroidDelayLoadApp)
|
|
72
77
|
buildConfigField("boolean", "USE_DEV_CLIENT", useDevClient.toString())
|
|
73
78
|
}
|
|
@@ -108,7 +108,7 @@ interface IUpdatesController {
|
|
|
108
108
|
this["runtimeVersion"] = runtimeVersion ?: ""
|
|
109
109
|
this["checkAutomatically"] = checkOnLaunch.toJSString()
|
|
110
110
|
this["channel"] = requestHeaders["expo-channel-name"] ?: ""
|
|
111
|
-
this["shouldDeferToNativeForAPIMethodAvailabilityInDevelopment"] = shouldDeferToNativeForAPIMethodAvailabilityInDevelopment ||
|
|
111
|
+
this["shouldDeferToNativeForAPIMethodAvailabilityInDevelopment"] = shouldDeferToNativeForAPIMethodAvailabilityInDevelopment || UpdatesPackage.isUsingNativeDebug
|
|
112
112
|
this["initialContext"] = initialContext.bundle
|
|
113
113
|
|
|
114
114
|
if (launchedUpdate != null) {
|
|
@@ -33,7 +33,7 @@ class UpdatesController {
|
|
|
33
33
|
return
|
|
34
34
|
}
|
|
35
35
|
val useDeveloperSupport = (context as? ReactApplication)?.reactNativeHost?.useDeveloperSupport ?: false
|
|
36
|
-
if (useDeveloperSupport && !
|
|
36
|
+
if (useDeveloperSupport && !UpdatesPackage.isUsingNativeDebug) {
|
|
37
37
|
if (BuildConfig.USE_DEV_CLIENT) {
|
|
38
38
|
val devLauncherController = initializeAsDevLauncherWithoutStarting(context)
|
|
39
39
|
singletonInstance = devLauncherController
|
|
@@ -22,7 +22,6 @@ import kotlinx.coroutines.withContext
|
|
|
22
22
|
* applicable environments.
|
|
23
23
|
*/
|
|
24
24
|
class UpdatesPackage : Package {
|
|
25
|
-
private val useNativeDebug = BuildConfig.EX_UPDATES_NATIVE_DEBUG
|
|
26
25
|
|
|
27
26
|
override fun createReactNativeHostHandlers(context: Context): List<ReactNativeHostHandler> {
|
|
28
27
|
val handler: ReactNativeHostHandler = object : ReactNativeHostHandler {
|
|
@@ -57,12 +56,12 @@ class UpdatesPackage : Package {
|
|
|
57
56
|
override fun createReactActivityHandlers(activityContext: Context): List<ReactActivityHandler> {
|
|
58
57
|
val handler = object : ReactActivityHandler {
|
|
59
58
|
override fun getDelayLoadAppHandler(activity: ReactActivity, reactNativeHost: ReactNativeHost): ReactActivityHandler.DelayLoadAppHandler? {
|
|
60
|
-
if (!BuildConfig.EX_UPDATES_ANDROID_DELAY_LOAD_APP) {
|
|
59
|
+
if (!BuildConfig.EX_UPDATES_ANDROID_DELAY_LOAD_APP || isUsingCustomInit) {
|
|
61
60
|
return null
|
|
62
61
|
}
|
|
63
62
|
val context = activity.applicationContext
|
|
64
63
|
val useDeveloperSupport = reactNativeHost.useDeveloperSupport
|
|
65
|
-
if (!useDeveloperSupport ||
|
|
64
|
+
if (!useDeveloperSupport || isUsingNativeDebug) {
|
|
66
65
|
return ReactActivityHandler.DelayLoadAppHandler { whenReadyRunnable ->
|
|
67
66
|
CoroutineScope(Dispatchers.IO).launch {
|
|
68
67
|
startUpdatesController(context)
|
|
@@ -76,9 +75,11 @@ class UpdatesPackage : Package {
|
|
|
76
75
|
@WorkerThread
|
|
77
76
|
private suspend fun startUpdatesController(context: Context) {
|
|
78
77
|
withContext(Dispatchers.IO) {
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
78
|
+
if (!UpdatesPackage.isUsingCustomInit) {
|
|
79
|
+
UpdatesController.initialize(context)
|
|
80
|
+
// Call the synchronous `launchAssetFile()` function to wait for updates ready
|
|
81
|
+
UpdatesController.instance.launchAssetFile
|
|
82
|
+
}
|
|
82
83
|
}
|
|
83
84
|
}
|
|
84
85
|
|
|
@@ -119,5 +120,7 @@ class UpdatesPackage : Package {
|
|
|
119
120
|
|
|
120
121
|
companion object {
|
|
121
122
|
private val TAG = UpdatesPackage::class.java.simpleName
|
|
123
|
+
val isUsingNativeDebug = BuildConfig.EX_UPDATES_NATIVE_DEBUG
|
|
124
|
+
internal val isUsingCustomInit = BuildConfig.EX_UPDATES_CUSTOM_INIT
|
|
122
125
|
}
|
|
123
126
|
}
|
|
@@ -24,9 +24,6 @@
|
|
|
24
24
|
},
|
|
25
25
|
"updates_testing_debug": {
|
|
26
26
|
"extends": "base",
|
|
27
|
-
"env": {
|
|
28
|
-
"EX_UPDATES_NATIVE_DEBUG": "1"
|
|
29
|
-
},
|
|
30
27
|
"android": {
|
|
31
28
|
"applicationArchivePath": "eas.json",
|
|
32
29
|
"gradleCommand": ":app:assembleDebug :app:assembleAndroidTest -DtestBuildType=debug",
|
|
@@ -42,9 +39,6 @@
|
|
|
42
39
|
},
|
|
43
40
|
"updates_testing_release": {
|
|
44
41
|
"extends": "base",
|
|
45
|
-
"env": {
|
|
46
|
-
"EX_UPDATES_NATIVE_DEBUG": "1"
|
|
47
|
-
},
|
|
48
42
|
"android": {
|
|
49
43
|
"gradleCommand": ":app:assembleRelease :app:assembleAndroidTest -DtestBuildType=release",
|
|
50
44
|
"withoutCredentials": true
|
package/e2e/setup/project.ts
CHANGED
|
@@ -757,7 +757,6 @@ export async function initAsync(
|
|
|
757
757
|
await spawnAsync(localCliBin, ['prebuild', '--no-install', '--template', localTemplatePathName], {
|
|
758
758
|
env: {
|
|
759
759
|
...process.env,
|
|
760
|
-
EX_UPDATES_NATIVE_DEBUG: '1',
|
|
761
760
|
EXPO_DEBUG: '1',
|
|
762
761
|
CI: '1',
|
|
763
762
|
},
|
|
@@ -784,7 +783,7 @@ export async function initAsync(
|
|
|
784
783
|
// enable proguard on Android
|
|
785
784
|
await fs.appendFile(
|
|
786
785
|
path.join(projectRoot, 'android', 'gradle.properties'),
|
|
787
|
-
'\nandroid.enableProguardInReleaseBuilds=true\
|
|
786
|
+
'\nandroid.enableProguardInReleaseBuilds=true\nEX_UPDATES_NATIVE_DEBUG=true',
|
|
788
787
|
'utf-8'
|
|
789
788
|
);
|
|
790
789
|
|
|
@@ -804,6 +803,18 @@ export async function initAsync(
|
|
|
804
803
|
].join('\n'),
|
|
805
804
|
'utf-8'
|
|
806
805
|
);
|
|
806
|
+
|
|
807
|
+
// Add native debug to iOS Podfile.properties.json
|
|
808
|
+
const podfilePropertiesJsonPath = path.join(projectRoot, 'ios', 'Podfile.properties.json');
|
|
809
|
+
const podfilePropertiesJsonString = await fs.readFile(podfilePropertiesJsonPath, {
|
|
810
|
+
encoding: 'utf-8',
|
|
811
|
+
});
|
|
812
|
+
const podfilePropertiesJson: any = JSON.parse(podfilePropertiesJsonString);
|
|
813
|
+
podfilePropertiesJson.updatesNativeDebug = 'true';
|
|
814
|
+
await fs.writeFile(podfilePropertiesJsonPath, JSON.stringify(podfilePropertiesJson, null, 2), {
|
|
815
|
+
encoding: 'utf-8',
|
|
816
|
+
});
|
|
817
|
+
|
|
807
818
|
await fs.appendFile(
|
|
808
819
|
path.join(projectRoot, 'android', 'app', 'build.gradle'),
|
|
809
820
|
[
|
package/expo-updates-gradle-plugin/src/main/kotlin/expo/modules/updates/ExpoUpdatesPlugin.kt
CHANGED
|
@@ -16,6 +16,7 @@ import org.slf4j.LoggerFactory
|
|
|
16
16
|
import java.io.ByteArrayOutputStream
|
|
17
17
|
import java.io.File
|
|
18
18
|
import java.util.Locale
|
|
19
|
+
import java.util.Properties
|
|
19
20
|
|
|
20
21
|
abstract class ExpoUpdatesPlugin : Plugin<Project> {
|
|
21
22
|
override fun apply(project: Project) {
|
|
@@ -26,7 +27,7 @@ abstract class ExpoUpdatesPlugin : Plugin<Project> {
|
|
|
26
27
|
val entryFile = detectedEntryFile(reactExtension)
|
|
27
28
|
val androidComponents = project.extensions.getByType(AndroidComponentsExtension::class.java)
|
|
28
29
|
|
|
29
|
-
if (
|
|
30
|
+
if (isNativeDebuggingEnabled(project)) {
|
|
30
31
|
logger.warn("Disable all react.debuggableVariants because EX_UPDATES_NATIVE_DEBUG=1")
|
|
31
32
|
reactExtension.debuggableVariants.set(listOf())
|
|
32
33
|
}
|
|
@@ -126,3 +127,10 @@ private fun detectedEntryFile(config: ReactExtension): File {
|
|
|
126
127
|
else -> File(reactRoot, "index.js")
|
|
127
128
|
}
|
|
128
129
|
}
|
|
130
|
+
|
|
131
|
+
private fun isNativeDebuggingEnabled(project: Project): Boolean {
|
|
132
|
+
if (System.getenv("EX_UPDATES_NATIVE_DEBUG") == "1") {
|
|
133
|
+
return true
|
|
134
|
+
}
|
|
135
|
+
return project.findProperty("EX_UPDATES_NATIVE_DEBUG") == "true"
|
|
136
|
+
}
|
|
@@ -22,6 +22,10 @@ public final class ExpoUpdatesReactDelegateHandler: ExpoReactDelegateHandler, Ap
|
|
|
22
22
|
initialProperties: [AnyHashable: Any]?,
|
|
23
23
|
launchOptions: [UIApplication.LaunchOptionsKey: Any]?
|
|
24
24
|
) -> UIView? {
|
|
25
|
+
if UpdatesUtils.isUsingCustomInitialization() {
|
|
26
|
+
return nil
|
|
27
|
+
}
|
|
28
|
+
|
|
25
29
|
AppController.initializeWithoutStarting()
|
|
26
30
|
let controller = AppController.sharedInstance
|
|
27
31
|
if !controller.isActiveController {
|
|
@@ -59,6 +63,9 @@ public final class ExpoUpdatesReactDelegateHandler: ExpoReactDelegateHandler, Ap
|
|
|
59
63
|
// MARK: AppControllerDelegate implementations
|
|
60
64
|
|
|
61
65
|
public func appController(_ appController: AppControllerInterface, didStartWithSuccess success: Bool) {
|
|
66
|
+
if UpdatesUtils.isUsingCustomInitialization() {
|
|
67
|
+
return
|
|
68
|
+
}
|
|
62
69
|
guard let reactDelegate = self.reactDelegate else {
|
|
63
70
|
fatalError("`reactDelegate` should not be nil")
|
|
64
71
|
}
|
|
@@ -133,7 +133,7 @@ public final class UpdatesUtils: NSObject {
|
|
|
133
133
|
}
|
|
134
134
|
}
|
|
135
135
|
|
|
136
|
-
|
|
136
|
+
public static func isNativeDebuggingEnabled() -> Bool {
|
|
137
137
|
#if EX_UPDATES_NATIVE_DEBUG
|
|
138
138
|
return true
|
|
139
139
|
#else
|
|
@@ -141,6 +141,14 @@ public final class UpdatesUtils: NSObject {
|
|
|
141
141
|
#endif
|
|
142
142
|
}
|
|
143
143
|
|
|
144
|
+
internal static func isUsingCustomInitialization() -> Bool {
|
|
145
|
+
#if EX_UPDATES_CUSTOM_INIT
|
|
146
|
+
return true
|
|
147
|
+
#else
|
|
148
|
+
return false
|
|
149
|
+
#endif
|
|
150
|
+
}
|
|
151
|
+
|
|
144
152
|
internal static func runBlockOnMainThread(_ block: @escaping () -> Void) {
|
|
145
153
|
if Thread.isMainThread {
|
|
146
154
|
block()
|
package/ios/EXUpdates.podspec
CHANGED
|
@@ -3,9 +3,19 @@ require 'json'
|
|
|
3
3
|
package = JSON.parse(File.read(File.join(__dir__, '..', 'package.json')))
|
|
4
4
|
podfile_properties = JSON.parse(File.read("#{Pod::Config.instance.installation_root}/Podfile.properties.json")) rescue {}
|
|
5
5
|
|
|
6
|
+
if ENV['EX_UPDATES_NATIVE_DEBUG'] != '1'
|
|
7
|
+
ENV['EX_UPDATES_NATIVE_DEBUG'] = podfile_properties['updatesNativeDebug'] == 'true' ? '1' : '0'
|
|
8
|
+
end
|
|
9
|
+
if ENV['EX_UPDATES_CUSTOM_INIT'] != '1'
|
|
10
|
+
ENV['EX_UPDATES_CUSTOM_INIT'] = podfile_properties['updatesCustomInit'] == 'true' ? '1' : '0'
|
|
11
|
+
end
|
|
12
|
+
|
|
6
13
|
use_dev_client = false
|
|
7
14
|
begin
|
|
8
|
-
|
|
15
|
+
# No dev client if we are using native debug
|
|
16
|
+
if ENV['EX_UPDATES_NATIVE_DEBUG'] != '1'
|
|
17
|
+
use_dev_client = `node --print "require('expo-dev-client/package.json').version" 2>/dev/null`.length > 0
|
|
18
|
+
end
|
|
9
19
|
rescue
|
|
10
20
|
use_dev_client = false
|
|
11
21
|
end
|
|
@@ -43,17 +53,26 @@ Pod::Spec.new do |s|
|
|
|
43
53
|
end
|
|
44
54
|
install_modules_dependencies(s)
|
|
45
55
|
|
|
46
|
-
|
|
47
|
-
|
|
56
|
+
other_debug_c_flags = '$(inherited)'
|
|
57
|
+
other_debug_swift_flags = '$(inherited)'
|
|
58
|
+
other_release_c_flags = '$(inherited)'
|
|
59
|
+
other_release_swift_flags = '$(inherited)'
|
|
48
60
|
|
|
49
61
|
ex_updates_native_debug = ENV['EX_UPDATES_NATIVE_DEBUG'] == '1'
|
|
62
|
+
ex_updates_custom_init = ENV['EX_UPDATES_CUSTOM_INIT'] == '1'
|
|
50
63
|
if ex_updates_native_debug
|
|
51
|
-
|
|
52
|
-
|
|
64
|
+
other_debug_c_flags << ' -DEX_UPDATES_NATIVE_DEBUG=1'
|
|
65
|
+
other_debug_swift_flags << ' -DEX_UPDATES_NATIVE_DEBUG'
|
|
66
|
+
end
|
|
67
|
+
if ex_updates_custom_init
|
|
68
|
+
other_debug_c_flags << ' -DEX_UPDATES_CUSTOM_INIT=1'
|
|
69
|
+
other_debug_swift_flags << ' -DEX_UPDATES_CUSTOM_INIT'
|
|
70
|
+
other_release_c_flags << ' -DEX_UPDATES_CUSTOM_INIT=1'
|
|
71
|
+
other_release_swift_flags << ' -DEX_UPDATES_CUSTOM_INIT'
|
|
53
72
|
end
|
|
54
73
|
if use_dev_client
|
|
55
|
-
|
|
56
|
-
|
|
74
|
+
other_debug_c_flags << ' -DUSE_DEV_CLIENT=1'
|
|
75
|
+
other_debug_swift_flags << ' -DUSE_DEV_CLIENT'
|
|
57
76
|
end
|
|
58
77
|
|
|
59
78
|
s.pod_target_xcconfig = {
|
|
@@ -61,8 +80,10 @@ Pod::Spec.new do |s|
|
|
|
61
80
|
'GCC_TREAT_IMPLICIT_FUNCTION_DECLARATIONS_AS_ERRORS' => 'YES',
|
|
62
81
|
'DEFINES_MODULE' => 'YES',
|
|
63
82
|
'SWIFT_COMPILATION_MODE' => 'wholemodule',
|
|
64
|
-
'OTHER_CFLAGS[config=*Debug*]' =>
|
|
65
|
-
'OTHER_SWIFT_FLAGS[config=*Debug*]' =>
|
|
83
|
+
'OTHER_CFLAGS[config=*Debug*]' => other_debug_c_flags,
|
|
84
|
+
'OTHER_SWIFT_FLAGS[config=*Debug*]' => other_debug_swift_flags,
|
|
85
|
+
'OTHER_CFLAGS[config=*Release*]' => other_release_c_flags,
|
|
86
|
+
'OTHER_SWIFT_FLAGS[config=*Release*]' => other_release_swift_flags
|
|
66
87
|
}
|
|
67
88
|
s.user_target_xcconfig = {
|
|
68
89
|
'HEADER_SEARCH_PATHS' => '"${PODS_CONFIGURATION_BUILD_DIR}/EXUpdates/Swift Compatibility Header"',
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "expo-updates",
|
|
3
|
-
"version": "0.27.
|
|
3
|
+
"version": "0.27.4",
|
|
4
4
|
"description": "Fetches and manages remotely-hosted assets and updates to your app's JS bundle.",
|
|
5
5
|
"main": "build/index.js",
|
|
6
6
|
"types": "build/index.d.ts",
|
|
@@ -67,5 +67,5 @@
|
|
|
67
67
|
"expo": "*",
|
|
68
68
|
"react": "*"
|
|
69
69
|
},
|
|
70
|
-
"gitHead": "
|
|
70
|
+
"gitHead": "3d777be5908ef1cfd1aab88e9807a6b0295ae96b"
|
|
71
71
|
}
|