Skip to content

Commit c020951

Browse files
naveen-bitriseCHOIMINSEOKkmsbernardMinseok Choi
authored
Expo Fix: Improve New Architecture JS bundle reload on Android by prioritizing reactHost.reload() (#20)
* classCastException caught in loadBundle * removed debug comments * Added Expo Example Project * updated android bundle name to index.android.bundle * Added iOS instructions to Readme in CodePushExpoDemoApp * Updated iOS instructions in Readme in CodePushExpoDemoApp * Updated Readme in CodePushExpoDemoApp to mention codepush expo plugin * updated Readme to include zipping the updates * minor Readme corrections * add expo test-app setup-1 * refactored expo codepush plugin * expo setup for test - 2 * expo setup for test - 3 * override TestAppName * fix android test * fix bundling script * fix bundling script * using react-native bundle instead of expo export during expo test * moved expo plugin file to CodePushExpoDemoApp * moved expo.js to root * 1. Expo plugin refactor, and an issue in modifying buildTypes block in app/build.gradle fixed 2. Added addtional debug looging to App.js 3. Update README * expo plugin refactor, and README update * add expo plugin guide --------- Co-authored-by: CHOIMINSEOK <cms3718@gmail.com> Co-authored-by: Minsik Kim <kmsbernard@gmail.com> Co-authored-by: Minseok Choi <minseokchoi@Minseoks-MacBook-Pro.local>
1 parent 57bf38a commit c020951

File tree

22 files changed

+10581
-267
lines changed

22 files changed

+10581
-267
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,3 +192,6 @@ Examples/testapp_rn
192192

193193
# Android debug build files (conflict ignoring #Visual Studio files)
194194
!android/app/src/debug/
195+
196+
#CodePushExpoDemoApp
197+
*.rm
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
# Learn more https://docs.github.com/en/get-started/getting-started-with-git/ignoring-files
2+
3+
# dependencies
4+
node_modules/
5+
6+
# Expo
7+
.expo/
8+
dist/
9+
web-build/
10+
expo-env.d.ts
11+
12+
# Native
13+
.kotlin/
14+
*.orig.*
15+
*.jks
16+
*.p8
17+
*.p12
18+
*.key
19+
*.mobileprovision
20+
21+
# Metro
22+
.metro-health-check*
23+
24+
# debug
25+
npm-debug.*
26+
yarn-debug.*
27+
yarn-error.*
28+
29+
# macOS
30+
.DS_Store
31+
*.pem
32+
33+
# local env files
34+
.env*.local
35+
36+
# typescript
37+
*.tsbuildinfo
38+
39+
#expo prebuild
40+
android/*
41+
ios/*
42+
43+
#build
44+
build/*
45+
46+
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
import { StatusBar } from 'expo-status-bar';
2+
import React, { useState, useEffect } from 'react';
3+
import { StyleSheet, Text, View } from 'react-native';
4+
import codePush from '@code-push-next/react-native-code-push';
5+
6+
function App() {
7+
// Log current package information on app start
8+
useEffect(() => {
9+
// Add custom error handler
10+
const originalConsoleError = console.error.bind(console);
11+
console.error = function (message, ...args) {
12+
console.log("[CodePushDebug] Error intercepted:", message, ...args);
13+
return originalConsoleError(message, ...args);
14+
};
15+
16+
// Monitor network requests
17+
const originalFetch = global.fetch;
18+
global.fetch = function (input, init) {
19+
console.log("[CodePushDebug] Fetch request to:", typeof input === 'string' ? input : 'Request object');
20+
return originalFetch(input, init)
21+
.then(response => {
22+
console.log("[CodePushDebug] Fetch success for:", typeof input === 'string' ? input : 'Request object');
23+
return response;
24+
})
25+
.catch(error => {
26+
console.log("[CodePushDebug] Fetch error:", error);
27+
throw error;
28+
});
29+
};
30+
31+
codePush.getUpdateMetadata().then((metadata) => {
32+
if (metadata) {
33+
console.log('[CodePush] Running binary version: ' + metadata.appVersion);
34+
console.log('[CodePush] Running with CodePush update: ' + metadata.label);
35+
console.log('[CodePush] Package hash: ' + metadata.packageHash);
36+
console.log('[CodePush] Package description: ' + metadata.description);
37+
} else {
38+
console.log('[CodePush] Running binary version with no CodePush updates installed');
39+
}
40+
41+
// After getting metadata, check for updates
42+
console.log('[CodePush] Checking for update.');
43+
}).catch(err => {
44+
console.log('[CodePush] Error getting metadata:', err);
45+
});
46+
}, []);
47+
48+
return (
49+
<View style={styles.container}>
50+
<Text>Open up App.js to start working on your app!</Text>
51+
<StatusBar style="auto" />
52+
</View>
53+
);
54+
}
55+
56+
const styles = StyleSheet.create({
57+
container: {
58+
flex: 1,
59+
backgroundColor: '#fff',
60+
alignItems: 'center',
61+
justifyContent: 'center',
62+
},
63+
});
64+
65+
// CodePush configuration (remains the same as your original file)
66+
const codePushOptions = {
67+
checkFrequency: codePush.CheckFrequency.ON_APP_START,
68+
installMode: codePush.InstallMode.IMMEDIATE,
69+
mandatoryInstallMode: codePush.InstallMode.IMMEDIATE,
70+
updateDialog: {
71+
appendReleaseDescription: true,
72+
title: "Update Available",
73+
descriptionPrefix: "\n\nRelease Notes:\n",
74+
mandatoryContinueButtonLabel: "Install Now",
75+
mandatoryUpdateMessage: "An update is available that must be installed.",
76+
optionalIgnoreButtonLabel: "Later",
77+
optionalInstallButtonLabel: "Install Now",
78+
optionalUpdateMessage: "An update is available. Would you like to install it?"
79+
}
80+
};
81+
82+
export default codePush(codePushOptions)(App);
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
This is a [**React Native Expo**](https://docs.expo.dev/) project, created using the command `npx create-expo-app@latest --template blank`. The App.js file was then modified to add CodePush functionality. An expo plugin was added for CodePush in `codepush-plugin.js` and is configured in `app.json`
2+
3+
# Testing Codepush functionality
4+
5+
## Step 1: Set Codepush Server and Codepush Deployment key in app.json
6+
7+
In app.json set `CodePushDeploymentKey` and `CodePushServerURL` for ios and android.
8+
9+
## Step 2: Run expo prebuild
10+
11+
run `npx expo prebuild --clean`
12+
13+
## Step 3: Create release bundle
14+
15+
### Android
16+
17+
run `cd android && ./gradlew assembleRelease`
18+
19+
The apk bundle will be here `<project folder>/android/app/build/outputs/apk/release/app-release.apk`
20+
21+
Install the bundle on your android device, and open the app
22+
23+
### iOS
24+
25+
Create a release build by opening the `ios/CodePushExpoDemoApp.xcworkspace` in Xcode. Make sure it is a release build (in Xcode go to Product > Scheme > Edit Scheme > Select Run from left bar menu > verify that Release is selected in Build Configuration.). Choose a Simulator as well in Xcode, and Run. Wait till the app loads in simulator.
26+
27+
## Step 4: Make a change to App.js
28+
29+
Make a visible update to the App, by modifying App.js
30+
31+
## Step 5: Generate update Bundle
32+
33+
Run the following command to generate updated bundle
34+
35+
### Android
36+
37+
From in the project folder, run:
38+
39+
```
40+
npx expo export:embed \
41+
--entry-file index.js \
42+
--platform android \
43+
--dev false \
44+
--reset-cache \
45+
--bundle-output ./build/index.android.bundle \
46+
--assets-dest ./build \
47+
--minify false
48+
```
49+
50+
zip the build folder (include the build folder): `zip -r update.zip ./build`
51+
52+
### iOS
53+
54+
From the project folder, run:
55+
56+
```
57+
npx expo export:embed \
58+
--entry-file index.js \
59+
--platform ios \
60+
--dev false \
61+
--reset-cache \
62+
--bundle-output ./build/main.jsbundle \
63+
--assets-dest ./build \
64+
--minify false
65+
```
66+
67+
zip the build folder (include the build folder): `zip -r update.zip ./build`
68+
69+
## Step 6: Upload the update bundle to codepush server
70+
71+
Upload the update bundle zip to your codepush server following the instructions from the codepush server that you use
72+
73+
## Step 7: Open the app on your device
74+
75+
Close/kill the app, and reopen the app. When the app is opened, it will show that there is an update you can install
76+
77+
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
{
2+
"expo": {
3+
"name": "CodePushExpoDemoApp",
4+
"slug": "CodePushExpoDemoApp",
5+
"version": "1.2.1",
6+
"orientation": "portrait",
7+
"icon": "./assets/icon.png",
8+
"userInterfaceStyle": "light",
9+
"newArchEnabled": true,
10+
"splash": {
11+
"image": "./assets/splash-icon.png",
12+
"resizeMode": "contain",
13+
"backgroundColor": "#ffffff"
14+
},
15+
"ios": {
16+
"supportsTablet": true,
17+
"bundleIdentifier": "com.CodePushNext.ExpoDemoApp"
18+
},
19+
"android": {
20+
"adaptiveIcon": {
21+
"foregroundImage": "./assets/adaptive-icon.png",
22+
"backgroundColor": "#ffffff"
23+
},
24+
"edgeToEdgeEnabled": true,
25+
"package": "com.CodePushNext.ExpoDemoApp"
26+
},
27+
"web": {
28+
"favicon": "./assets/favicon.png"
29+
},
30+
"plugins": [
31+
[
32+
"@code-push-next/react-native-code-push/expo",
33+
{
34+
"ios": {
35+
"CodePushDeploymentKey": "Tf2qo0NCNKloj8Ym2Z2Bk_VQ_zLDNzk2MGNjNDktNWFiZS00NTAwLWFlNDEtZjMzNzllNGU0MjE0",
36+
"CodePushServerURL": "https://codepush.bitrise.io"
37+
},
38+
"android": {
39+
"CodePushDeploymentKey": "rUV0_iNflPqa3aJhVpciLnwgAFOaMzFiZjhhNDMtMGEyNS00NTk5LTk2ODEtOWU1NTcwODUwZTgx",
40+
"CodePushServerURL": "https://codepush.bitrise.io"
41+
}
42+
}
43+
],
44+
[
45+
"expo-build-properties",
46+
{
47+
"ios": {
48+
"deploymentTarget": "15.5"
49+
}
50+
}
51+
]
52+
]
53+
}
54+
}
17.1 KB
Loading
1.43 KB
Loading
21.9 KB
Loading
17.1 KB
Loading
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import { registerRootComponent } from 'expo';
2+
3+
import App from './App';
4+
5+
// registerRootComponent calls AppRegistry.registerComponent('main', () => App);
6+
// It also ensures that whether you load the app in Expo Go or in a native build,
7+
// the environment is set up appropriately
8+
registerRootComponent(App);

0 commit comments

Comments
 (0)