@appzung/react-native-code-push 5.7.1 → 6.4.2
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/CONTRIBUTING.md +17 -19
- package/CodePush.js +11 -4
- package/CodePush.podspec +3 -3
- package/README.md +93 -37
- package/android/app/src/main/java/com/microsoft/codepush/react/CodePush.java +44 -7
- package/android/app/src/main/java/com/microsoft/codepush/react/CodePushInvalidPublicKeyException.java +0 -0
- package/android/app/src/main/java/com/microsoft/codepush/react/CodePushNativeModule.java +77 -22
- package/android/app/src/main/java/com/microsoft/codepush/react/CodePushUpdateManager.java +14 -0
- package/android/app/src/main/java/com/microsoft/codepush/react/FileUtils.java +15 -1
- package/android/app/src/main/java/com/microsoft/codepush/react/TLSSocketFactory.java +72 -0
- package/android/codepush.gradle +1 -1
- package/docs/api-android.md +21 -3
- package/docs/api-js.md +3 -3
- package/docs/multi-deployment-testing-android.md +63 -22
- package/docs/multi-deployment-testing-ios.md +17 -11
- package/docs/setup-android.md +79 -19
- package/docs/setup-ios.md +57 -7
- package/docs/setup-windows.md +1 -1
- package/ios/CodePush/Base64/Base64/MF_Base64Additions.m +0 -0
- package/ios/CodePush/CodePush.m +104 -24
- package/ios/CodePush/JWT/Core/Algorithms/Base/JWTAlgorithm.h +0 -0
- package/ios/CodePush/JWT/Core/Algorithms/Base/JWTAlgorithmFactory.h +0 -0
- package/ios/CodePush/JWT/Core/Algorithms/Base/JWTAlgorithmFactory.m +0 -0
- package/ios/CodePush/JWT/Core/Algorithms/Base/JWTAlgorithmNone.h +0 -0
- package/ios/CodePush/JWT/Core/Algorithms/Base/JWTAlgorithmNone.m +0 -0
- package/ios/CodePush/JWT/Core/Algorithms/ESFamily/JWTAlgorithmESBase.h +0 -0
- package/ios/CodePush/JWT/Core/Algorithms/ESFamily/JWTAlgorithmESBase.m +0 -0
- package/ios/CodePush/JWT/Core/Algorithms/HSFamily/JWTAlgorithmHSBase.h +0 -0
- package/ios/CodePush/JWT/Core/Algorithms/HSFamily/JWTAlgorithmHSBase.m +0 -0
- package/ios/CodePush/JWT/Core/Algorithms/Holders/JWTAlgorithmDataHolder.h +0 -0
- package/ios/CodePush/JWT/Core/Algorithms/Holders/JWTAlgorithmDataHolder.m +0 -0
- package/ios/CodePush/JWT/Core/Algorithms/Holders/JWTAlgorithmDataHolderChain.h +0 -0
- package/ios/CodePush/JWT/Core/Algorithms/Holders/JWTAlgorithmDataHolderChain.m +0 -0
- package/ios/CodePush/JWT/Core/Algorithms/RSFamily/JWTAlgorithmRSBase.h +0 -0
- package/ios/CodePush/JWT/Core/Algorithms/RSFamily/JWTAlgorithmRSBase.m +0 -0
- package/ios/CodePush/JWT/Core/Algorithms/RSFamily/JWTRSAlgorithm.h +0 -0
- package/ios/CodePush/JWT/Core/Algorithms/RSFamily/RSKeys/JWTCryptoKey.h +0 -0
- package/ios/CodePush/JWT/Core/Algorithms/RSFamily/RSKeys/JWTCryptoKey.m +0 -0
- package/ios/CodePush/JWT/Core/Algorithms/RSFamily/RSKeys/JWTCryptoKeyExtractor.h +0 -0
- package/ios/CodePush/JWT/Core/Algorithms/RSFamily/RSKeys/JWTCryptoKeyExtractor.m +0 -0
- package/ios/CodePush/JWT/Core/Algorithms/RSFamily/RSKeys/JWTCryptoSecurity.h +0 -0
- package/ios/CodePush/JWT/Core/Algorithms/RSFamily/RSKeys/JWTCryptoSecurity.m +0 -0
- package/ios/CodePush/JWT/Core/ClaimSet/JWTClaim.h +0 -0
- package/ios/CodePush/JWT/Core/ClaimSet/JWTClaim.m +0 -0
- package/ios/CodePush/JWT/Core/ClaimSet/JWTClaimsSet.h +0 -0
- package/ios/CodePush/JWT/Core/ClaimSet/JWTClaimsSet.m +0 -0
- package/ios/CodePush/JWT/Core/ClaimSet/JWTClaimsSetSerializer.h +0 -0
- package/ios/CodePush/JWT/Core/ClaimSet/JWTClaimsSetSerializer.m +0 -0
- package/ios/CodePush/JWT/Core/ClaimSet/JWTClaimsSetVerifier.h +0 -0
- package/ios/CodePush/JWT/Core/ClaimSet/JWTClaimsSetVerifier.m +0 -0
- package/ios/CodePush/JWT/Core/Coding/JWTCoding+ResultTypes.h +0 -0
- package/ios/CodePush/JWT/Core/Coding/JWTCoding+ResultTypes.m +0 -0
- package/ios/CodePush/JWT/Core/Coding/JWTCoding+VersionOne.h +0 -0
- package/ios/CodePush/JWT/Core/Coding/JWTCoding+VersionOne.m +0 -0
- package/ios/CodePush/JWT/Core/Coding/JWTCoding+VersionThree.h +0 -0
- package/ios/CodePush/JWT/Core/Coding/JWTCoding+VersionThree.m +0 -0
- package/ios/CodePush/JWT/Core/Coding/JWTCoding+VersionTwo.h +0 -0
- package/ios/CodePush/JWT/Core/Coding/JWTCoding+VersionTwo.m +0 -0
- package/ios/CodePush/JWT/Core/Coding/JWTCoding.h +0 -0
- package/ios/CodePush/JWT/Core/Coding/JWTCoding.m +0 -0
- package/ios/CodePush/JWT/Core/FrameworkSupplement/JWT.h +0 -0
- package/ios/CodePush/JWT/Core/FrameworkSupplement/Map.modulemap +0 -0
- package/ios/CodePush/JWT/Core/Supplement/JWTBase64Coder.h +0 -0
- package/ios/CodePush/JWT/Core/Supplement/JWTBase64Coder.m +0 -0
- package/ios/CodePush/JWT/Core/Supplement/JWTDeprecations.h +0 -0
- package/ios/CodePush/JWT/Core/Supplement/JWTErrorDescription.h +0 -0
- package/ios/CodePush/JWT/Core/Supplement/JWTErrorDescription.m +0 -0
- package/ios/CodePush/SSZipArchive/Common.h +0 -0
- package/ios/CodePush/SSZipArchive/SSZipArchive.h +0 -0
- package/ios/CodePush/SSZipArchive/SSZipArchive.m +0 -0
- package/ios/CodePush/SSZipArchive/aes/aes.h +0 -0
- package/ios/CodePush/SSZipArchive/aes/aes_via_ace.h +0 -0
- package/ios/CodePush/SSZipArchive/aes/aescrypt.c +0 -0
- package/ios/CodePush/SSZipArchive/aes/aeskey.c +0 -0
- package/ios/CodePush/SSZipArchive/aes/aesopt.h +0 -0
- package/ios/CodePush/SSZipArchive/aes/aestab.c +0 -0
- package/ios/CodePush/SSZipArchive/aes/aestab.h +0 -0
- package/ios/CodePush/SSZipArchive/aes/brg_endian.h +0 -0
- package/ios/CodePush/SSZipArchive/aes/brg_types.h +0 -0
- package/ios/CodePush/SSZipArchive/aes/entropy.c +0 -0
- package/ios/CodePush/SSZipArchive/aes/entropy.h +0 -0
- package/ios/CodePush/SSZipArchive/aes/fileenc.c +0 -0
- package/ios/CodePush/SSZipArchive/aes/fileenc.h +0 -0
- package/ios/CodePush/SSZipArchive/aes/hmac.c +0 -0
- package/ios/CodePush/SSZipArchive/aes/hmac.h +0 -0
- package/ios/CodePush/SSZipArchive/aes/prng.c +0 -0
- package/ios/CodePush/SSZipArchive/aes/prng.h +0 -0
- package/ios/CodePush/SSZipArchive/aes/pwd2key.c +0 -0
- package/ios/CodePush/SSZipArchive/aes/pwd2key.h +0 -0
- package/ios/CodePush/SSZipArchive/aes/sha1.c +0 -0
- package/ios/CodePush/SSZipArchive/aes/sha1.h +0 -0
- package/ios/CodePush/SSZipArchive/minizip/crypt.h +0 -0
- package/ios/CodePush/SSZipArchive/minizip/ioapi.c +0 -0
- package/ios/CodePush/SSZipArchive/minizip/ioapi.h +0 -0
- package/ios/CodePush/SSZipArchive/minizip/mztools.c +0 -0
- package/ios/CodePush/SSZipArchive/minizip/mztools.h +0 -0
- package/ios/CodePush/SSZipArchive/minizip/unzip.c +0 -0
- package/ios/CodePush/SSZipArchive/minizip/unzip.h +0 -0
- package/ios/CodePush/SSZipArchive/minizip/zip.c +0 -0
- package/ios/CodePush/SSZipArchive/minizip/zip.h +0 -0
- package/package-mixins.js +2 -3
- package/package.json +36 -13
- package/react-native.config.js +10 -0
- package/request-fetch-adapter.js +1 -1
- package/scripts/generateBundledResourcesHash.js +1 -1
- package/scripts/postlink/android/postlink.js +2 -2
- package/scripts/postunlink/android/postunlink.js +3 -3
- package/scripts/tools/linkToolsAndroid.js +1 -1
- package/scripts/tools/linkToolsIos.js +2 -2
- package/tsconfig.json +14 -0
- package/tslint.json +32 -0
- package/typings/react-native-code-push.d.ts +14 -5
- package/RestartManager.js +0 -59
- package/gulpfile.js +0 -302
package/CONTRIBUTING.md
CHANGED
|
@@ -37,13 +37,13 @@ Follow these steps to test your modifications to the plugin manually:
|
|
|
37
37
|
|
|
38
38
|
First, make sure you have installed the dependencies for the plugin by following the steps above.
|
|
39
39
|
|
|
40
|
-
Then, make sure you have installed `
|
|
40
|
+
Then, make sure you have installed `react-native-cli`.
|
|
41
41
|
|
|
42
42
|
```
|
|
43
|
-
npm install -g
|
|
43
|
+
npm install -g react-native-cli
|
|
44
44
|
```
|
|
45
45
|
|
|
46
|
-
To run Android tests, make sure you have `sdk\tools` and `sdk\platform-tools` in your PATH.
|
|
46
|
+
To run Android tests, make sure you have `sdk\tools`, `sdk\emulator` and `sdk\platform-tools` in your PATH.
|
|
47
47
|
|
|
48
48
|
To run iOS tests, make sure you've installed CocoaPods and have `.gem/bin` in your PATH.
|
|
49
49
|
|
|
@@ -62,43 +62,41 @@ The tests first build the app.
|
|
|
62
62
|
|
|
63
63
|
They then check if the required emulators are currently running.
|
|
64
64
|
|
|
65
|
-
If an Android emulator is not running, it attempts to boot
|
|
65
|
+
If an Android emulator is not running, it attempts to boot the latest Android emulator. You can specify an emulator by adding env variable `ANDROID_EMU=yourEmulatorNameHere` to the npm command. For example: `ANDROID_EMU=yourEmulatorNameHere npm run test:android`.
|
|
66
66
|
|
|
67
|
-
If an iOS simulator is not running, it attempts to boot the latest iOS iPhone simulator. You can specify a simulator by adding
|
|
67
|
+
If an iOS simulator is not running, it attempts to boot the latest iOS iPhone simulator. You can specify a simulator by adding env variable `IOS_EMU=yourSimulatorNameHere` to the npm command. For example: `IOS_EMU="iPhone 8 (0567DFF8-329E-41A3-BD6D-E48E9DD5EF39)" npm run test:ios`.
|
|
68
68
|
|
|
69
69
|
If all the required emulators are not running and the tests fail to boot them, the tests will fail.
|
|
70
70
|
|
|
71
|
-
If you would like the tests to always restart the necessary emulators (killing them if they are currently running),
|
|
71
|
+
If you would like the tests to always restart the necessary emulators (killing them if they are currently running), setup a env variable `CLEAN=true` to the command. For example: `CLEAN=true npm run test`.
|
|
72
72
|
|
|
73
73
|
The desired unit tests are then run.
|
|
74
74
|
|
|
75
|
-
If you would like to skip building, add a
|
|
75
|
+
If you would like to skip building, add a `:fast` in the command you'd like to run. For example, `npm run test:ios` becomes `npm run test:fast:ios` or `npm run test:android` becomes `npm run test:fast:android`.
|
|
76
76
|
|
|
77
|
-
There is a both a full unit test suite and a "core" set of unit tests that you may run. If you would like to run only the core tests,
|
|
77
|
+
There is a both a full unit test suite and a "core" set of unit tests that you may run. If you would like to run only the core tests, setup a env variable `CORE=true` to the command. For example: `CORE=true npm run test:android`.
|
|
78
78
|
|
|
79
|
-
If you would like to pull the plugin from NPM rather than running the tests on the local version,
|
|
80
|
-
|
|
81
|
-
If you add a `--report` flag to the command, the mocha reporter outputs individual results files for each platform. These are `./test_android.xml`, `./test-ios-ui.xml`, and `./test-ios-wk.xml`.
|
|
79
|
+
If you would like to pull the plugin from NPM rather than running the tests on the local version, setup a env variable `NPM=true` to the command. For example: `NPM=true npm run test:ios`.
|
|
82
80
|
|
|
83
81
|
#### Default
|
|
84
82
|
|
|
85
83
|
To run all of the unit tests on Android and iOS:
|
|
86
84
|
```
|
|
87
|
-
|
|
85
|
+
npm run test
|
|
88
86
|
```
|
|
89
87
|
|
|
90
88
|
#### iOS
|
|
91
89
|
|
|
92
90
|
To run all of the unit tests on iOS:
|
|
93
91
|
```
|
|
94
|
-
|
|
92
|
+
npm run test:ios
|
|
95
93
|
```
|
|
96
94
|
|
|
97
95
|
#### Android
|
|
98
96
|
|
|
99
97
|
To run all of the unit tests on Android:
|
|
100
98
|
```
|
|
101
|
-
|
|
99
|
+
npm run test:android
|
|
102
100
|
```
|
|
103
101
|
|
|
104
102
|
#### More examples
|
|
@@ -110,27 +108,27 @@ android, ios
|
|
|
110
108
|
|
|
111
109
|
To run the core unit tests on Android:
|
|
112
110
|
```
|
|
113
|
-
|
|
111
|
+
CORE=true npm run test:android
|
|
114
112
|
```
|
|
115
113
|
|
|
116
114
|
To run all of the unit tests on iOS and pull the plugin from NPM:
|
|
117
115
|
```
|
|
118
|
-
|
|
116
|
+
NPM=true npm run test:ios
|
|
119
117
|
```
|
|
120
118
|
|
|
121
119
|
To run all of the unit tests on Android and iOS without building first:
|
|
122
120
|
```
|
|
123
|
-
|
|
121
|
+
npm run test:fast
|
|
124
122
|
```
|
|
125
123
|
|
|
126
124
|
To run all of the unit tests on iOS and restart the emulators:
|
|
127
125
|
```
|
|
128
|
-
|
|
126
|
+
CLEAN=true npm run test:ios
|
|
129
127
|
```
|
|
130
128
|
|
|
131
129
|
To run the core unit tests on Android and pull the plugin from NPM:
|
|
132
130
|
```
|
|
133
|
-
|
|
131
|
+
NPM=true CORE=true npm run test:android
|
|
134
132
|
```
|
|
135
133
|
|
|
136
134
|
...and so on!
|
package/CodePush.js
CHANGED
|
@@ -2,7 +2,6 @@ import { AcquisitionManager as Sdk } from "code-push/script/acquisition-sdk";
|
|
|
2
2
|
import { Alert } from "./AlertAdapter";
|
|
3
3
|
import requestFetchAdapter from "./request-fetch-adapter";
|
|
4
4
|
import { AppState, Platform } from "react-native";
|
|
5
|
-
import RestartManager from "./RestartManager";
|
|
6
5
|
import log from "./logging";
|
|
7
6
|
import hoistStatics from 'hoist-non-react-statics';
|
|
8
7
|
|
|
@@ -189,6 +188,10 @@ async function tryReportStatus(statusReport, resumeListener) {
|
|
|
189
188
|
if (statusReport.appVersion) {
|
|
190
189
|
log(`Reporting binary update (${statusReport.appVersion})`);
|
|
191
190
|
|
|
191
|
+
if (!config.deploymentKey) {
|
|
192
|
+
throw new Error("Deployment key is missed");
|
|
193
|
+
}
|
|
194
|
+
|
|
192
195
|
const sdk = getPromisifiedSdk(requestFetchAdapter, config);
|
|
193
196
|
await sdk.reportStatusDeploy(/* deployedPackage */ null, /* status */ null, previousLabelOrAppVersion, previousDeploymentKey);
|
|
194
197
|
} else {
|
|
@@ -300,6 +303,10 @@ function setUpTestDependencies(testSdk, providedTestConfig, testNativeBridge) {
|
|
|
300
303
|
if (testNativeBridge) NativeCodePush = testNativeBridge;
|
|
301
304
|
}
|
|
302
305
|
|
|
306
|
+
async function restartApp(onlyIfUpdateIsPending = false) {
|
|
307
|
+
NativeCodePush.restartApp(onlyIfUpdateIsPending);
|
|
308
|
+
}
|
|
309
|
+
|
|
303
310
|
// This function allows only one syncInternal operation to proceed at any given time.
|
|
304
311
|
// Parallel calls to sync() while one is ongoing yields CodePush.SyncStatus.SYNC_IN_PROGRESS.
|
|
305
312
|
const sync = (() => {
|
|
@@ -605,11 +612,11 @@ if (NativeCodePush) {
|
|
|
605
612
|
log,
|
|
606
613
|
notifyAppReady: notifyApplicationReady,
|
|
607
614
|
notifyApplicationReady,
|
|
608
|
-
restartApp
|
|
615
|
+
restartApp,
|
|
609
616
|
setUpTestDependencies,
|
|
610
617
|
sync,
|
|
611
|
-
disallowRestart:
|
|
612
|
-
allowRestart:
|
|
618
|
+
disallowRestart: NativeCodePush.disallow,
|
|
619
|
+
allowRestart: NativeCodePush.allow,
|
|
613
620
|
clearUpdates: NativeCodePush.clearUpdates,
|
|
614
621
|
InstallMode: {
|
|
615
622
|
IMMEDIATE: NativeCodePush.codePushInstallModeImmediate, // Restart the app immediately
|
package/CodePush.podspec
CHANGED
|
@@ -20,8 +20,8 @@ Pod::Spec.new do |s|
|
|
|
20
20
|
# Note: Even though there are copy/pasted versions of some of these dependencies in the repo,
|
|
21
21
|
# we explicitly let CocoaPods pull in the versions below so all dependencies are resolved and
|
|
22
22
|
# linked properly at a parent workspace level.
|
|
23
|
-
s.dependency 'React'
|
|
24
|
-
s.dependency 'SSZipArchive', '~> 2.
|
|
25
|
-
s.dependency 'JWT', '~> 3.0.0-beta.
|
|
23
|
+
s.dependency 'React-Core'
|
|
24
|
+
s.dependency 'SSZipArchive', '~> 2.2.2'
|
|
25
|
+
s.dependency 'JWT', '~> 3.0.0-beta.12'
|
|
26
26
|
s.dependency 'Base64', '~> 1.1'
|
|
27
27
|
end
|
package/README.md
CHANGED
|
@@ -1,13 +1,10 @@
|
|
|
1
|
-
UPDATE: Over the next few months, we will be working on a new version of CodePush that will address some of the most common performance issues our customers are facing. This updated version will allow a better experience, our team to better support CodePush moving forward and have a faster development cycle for new features.
|
|
2
|
-
We are prioritizing this work because we believe this to be the most valuable thing we can do for our CodePush customers in the long run. Starting June 11th 2019, support will slow down, bug fixes will be limited to critical bugs, and new feature development will pause until we finish this core update.
|
|
3
|
-
|
|
4
|
-
---
|
|
5
|
-
|
|
6
1
|
[](http://microsoft.github.io/code-push/)
|
|
7
2
|
|
|
3
|
+
#### [Sign up With App Center](https://appcenter.ms/signup?utm_source=CodePush&utm_medium=Azure) to use CodePush
|
|
4
|
+
|
|
8
5
|
# React Native Module for CodePush
|
|
9
6
|
|
|
10
|
-
*Note: This README is only relevant to the latest version of our plugin. If you are using an older version, please switch to the relevant tag on [our GitHub repo](https://github.com/
|
|
7
|
+
*Note: This README is only relevant to the latest version of our plugin. If you are using an older version, please switch to the relevant tag on [our GitHub repo](https://github.com/microsoft/react-native-code-push) to view the docs for that particular version.*
|
|
11
8
|
|
|
12
9
|

|
|
13
10
|
|
|
@@ -76,22 +73,27 @@ We try our best to maintain backwards compatibility of our plugin with previous
|
|
|
76
73
|
| v0.54-v0.55 | v5.3+ *(Android Gradle Plugin 3.x integration)* |
|
|
77
74
|
| v0.56-v0.58 | v5.4+ *(RN upgraded versions for Android tools)* |
|
|
78
75
|
| v0.59 | v5.6+ *(RN refactored js bundle loader code)* |
|
|
76
|
+
| v0.60-v0.61 | v6.0+ *(RN migrated to Autolinking)* |
|
|
77
|
+
| v0.62-v0.63 | v6.2+ *(RN removed LiveReload)* |
|
|
78
|
+
|
|
79
|
+
*NOTE: `react-native-code-push` versions lower than **[v5.7.0](https://github.com/microsoft/react-native-code-push/releases/tag/v5.7.0)** will stop working in the near future. You can find more information in our [documentation](https://github.com/microsoft/code-push/blob/master/migration-notice.md).*
|
|
79
80
|
|
|
80
81
|
We work hard to respond to new RN releases, but they do occasionally break us. We will update this chart with each RN release, so that users can check to see what our "official" support is.
|
|
81
82
|
|
|
82
83
|
### Supported Components
|
|
83
84
|
|
|
84
|
-
When using the React Native assets system (i.e. using the `require("./foo.png")` syntax), the following list represents the set of core components (and props) that support having their referenced images updated via CodePush:
|
|
85
|
+
When using the React Native assets system (i.e. using the `require("./foo.png")` syntax), the following list represents the set of core components (and props) that support having their referenced images and videos updated via CodePush:
|
|
85
86
|
|
|
86
87
|
| Component | Prop(s) |
|
|
87
88
|
|-------------------------------------------------|------------------------------------------|
|
|
88
|
-
| `Image` | `source`
|
|
89
|
+
| `Image` | `source` |
|
|
89
90
|
| `MapView.Marker` <br />*(Requires [react-native-maps](https://github.com/lelandrichardson/react-native-maps) `>=O.3.2`)* | `image` |
|
|
90
91
|
| `ProgressViewIOS` | `progressImage`, `trackImage` |
|
|
91
92
|
| `TabBarIOS.Item` | `icon`, `selectedIcon` |
|
|
92
93
|
| `ToolbarAndroid` <br />*(React Native 0.21.0+)* | `actions[].icon`, `logo`, `overflowIcon` |
|
|
94
|
+
| `Video` | `source` |
|
|
93
95
|
|
|
94
|
-
The following list represents the set of components (and props) that don't currently support their assets being updated via CodePush, due to their dependency on static images (i.e. using the `{ uri: "foo" }` syntax):
|
|
96
|
+
The following list represents the set of components (and props) that don't currently support their assets being updated via CodePush, due to their dependency on static images and videos (i.e. using the `{ uri: "foo" }` syntax):
|
|
95
97
|
|
|
96
98
|
| Component | Prop(s) |
|
|
97
99
|
|-------------|----------------------------------------------------------------------|
|
|
@@ -100,7 +102,11 @@ The following list represents the set of components (and props) that don't curre
|
|
|
100
102
|
|
|
101
103
|
As new core components are released, which support referencing assets, we'll update this list to ensure users know what exactly they can expect to update using CodePush.
|
|
102
104
|
|
|
105
|
+
*Note: CodePush only works with Video components when using `require` in the source prop. For example:*
|
|
103
106
|
|
|
107
|
+
```javascript
|
|
108
|
+
<Video source={require("./foo.mp4")} />
|
|
109
|
+
```
|
|
104
110
|
|
|
105
111
|
## Getting Started
|
|
106
112
|
|
|
@@ -134,6 +140,8 @@ The simplest way to do this is to "CodePush-ify" your app's root component. To d
|
|
|
134
140
|
|
|
135
141
|
* **Option 1: Wrap your root component with the `codePush` higher-order component:**
|
|
136
142
|
|
|
143
|
+
* For class component
|
|
144
|
+
|
|
137
145
|
```javascript
|
|
138
146
|
import codePush from "react-native-code-push";
|
|
139
147
|
|
|
@@ -143,10 +151,23 @@ The simplest way to do this is to "CodePush-ify" your app's root component. To d
|
|
|
143
151
|
MyApp = codePush(MyApp);
|
|
144
152
|
```
|
|
145
153
|
|
|
154
|
+
* For functional component
|
|
155
|
+
|
|
156
|
+
```javascript
|
|
157
|
+
import codePush from "react-native-code-push";
|
|
158
|
+
|
|
159
|
+
let MyApp: () => React$Node = () => {
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
MyApp = codePush(MyApp);
|
|
163
|
+
```
|
|
164
|
+
|
|
146
165
|
* **Option 2: Use the [ES7 decorator](https://github.com/wycats/javascript-decorators) syntax:**
|
|
147
166
|
|
|
148
167
|
*NOTE: Decorators are not yet supported in Babel 6.x pending proposal update.* You may need to enable it by installing and using [babel-preset-react-native-stage-0](https://github.com/skevy/babel-preset-react-native-stage-0#babel-preset-react-native-stage-0).
|
|
149
168
|
|
|
169
|
+
* For class component
|
|
170
|
+
|
|
150
171
|
```javascript
|
|
151
172
|
import codePush from "react-native-code-push";
|
|
152
173
|
|
|
@@ -155,18 +176,42 @@ The simplest way to do this is to "CodePush-ify" your app's root component. To d
|
|
|
155
176
|
}
|
|
156
177
|
```
|
|
157
178
|
|
|
179
|
+
* For functional component
|
|
180
|
+
|
|
181
|
+
```javascript
|
|
182
|
+
import codePush from "react-native-code-push";
|
|
183
|
+
|
|
184
|
+
const MyApp: () => React$Node = () => {
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
export default codePush(MyApp);
|
|
188
|
+
```
|
|
189
|
+
|
|
158
190
|
By default, CodePush will check for updates on every app start. If an update is available, it will be silently downloaded, and installed the next time the app is restarted (either explicitly by the end user or by the OS), which ensures the least invasive experience for your end users. If an available update is mandatory, then it will be installed immediately, ensuring that the end user gets it as soon as possible.
|
|
159
191
|
|
|
160
192
|
If you would like your app to discover updates more quickly, you can also choose to sync up with the CodePush server every time the app resumes from the background.
|
|
161
193
|
|
|
162
|
-
|
|
163
|
-
let codePushOptions = { checkFrequency: codePush.CheckFrequency.ON_APP_RESUME };
|
|
194
|
+
* For class component
|
|
164
195
|
|
|
165
|
-
|
|
166
|
-
}
|
|
196
|
+
```javascript
|
|
197
|
+
let codePushOptions = { checkFrequency: codePush.CheckFrequency.ON_APP_RESUME };
|
|
167
198
|
|
|
168
|
-
MyApp
|
|
169
|
-
|
|
199
|
+
class MyApp extends Component {
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
MyApp = codePush(codePushOptions)(MyApp);
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
* For functional component
|
|
206
|
+
|
|
207
|
+
```javascript
|
|
208
|
+
let codePushOptions = { checkFrequency: codePush.CheckFrequency.ON_APP_RESUME };
|
|
209
|
+
|
|
210
|
+
let MyApp: () => React$Node = () => {
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
MyApp = codePush(codePushOptions)(MyApp);
|
|
214
|
+
```
|
|
170
215
|
|
|
171
216
|
Alternatively, if you want fine-grained control over when the check happens (like a button press or timer interval), you can call [`CodePush.sync()`](docs/api-js.md#codepushsync) at any time with your desired `SyncOptions`, and optionally turn off CodePush's automatic checking by specifying a manual `checkFrequency`:
|
|
172
217
|
|
|
@@ -187,7 +232,7 @@ class MyApp extends Component {
|
|
|
187
232
|
<TouchableOpacity onPress={this.onButtonPress}>
|
|
188
233
|
<Text>Check for updates</Text>
|
|
189
234
|
</TouchableOpacity>
|
|
190
|
-
</View>
|
|
235
|
+
</View>
|
|
191
236
|
)
|
|
192
237
|
}
|
|
193
238
|
}
|
|
@@ -197,11 +242,20 @@ MyApp = codePush(codePushOptions)(MyApp);
|
|
|
197
242
|
|
|
198
243
|
If you would like to display an update confirmation dialog (an "active install"), configure when an available update is installed (like force an immediate restart) or customize the update experience in any other way, refer to the [`codePush()`](docs/api-js.md#codepush) API reference for information on how to tweak this default behavior.
|
|
199
244
|
|
|
200
|
-
*NOTE: If you are using [Redux](http://redux.js.org) and [Redux Saga](
|
|
245
|
+
*NOTE: If you are using [Redux](http://redux.js.org) and [Redux Saga](https://redux-saga.js.org/), you can alternatively use the [react-native-code-push-saga](http://github.com/lostintangent/react-native-code-push-saga) module, which allows you to customize when `sync` is called in a perhaps simpler/more idiomatic way.*
|
|
201
246
|
|
|
202
247
|
### Store Guideline Compliance
|
|
203
248
|
|
|
204
|
-
|
|
249
|
+
Android Google Play and iOS App Store have corresponding guidelines that have rules you should be aware of before integrating the CodePush solution within your application.
|
|
250
|
+
|
|
251
|
+
#### Google play
|
|
252
|
+
|
|
253
|
+
Third paragraph of [Device and Network Abuse](https://support.google.com/googleplay/android-developer/answer/9888379?hl=en) topic describe that updating source code by any method other than Google Play's update mechanism is restricted. But this restriction is not apply to updating javascript bundles.
|
|
254
|
+
> This restriction does not apply to code that runs in a virtual machine and has limited access to Android APIs (such as JavaScript in a webview or browser).
|
|
255
|
+
|
|
256
|
+
That fully allow CodePush as it updates just JS bundles and can't update native code part.
|
|
257
|
+
|
|
258
|
+
#### App Store
|
|
205
259
|
|
|
206
260
|
Paragraph **3.3.2**, since back in 2015's [Apple Developer Program License Agreement](https://developer.apple.com/programs/ios/information/) fully allowed performing over-the-air updates of JavaScript and assets - and in its latest version (20170605) [downloadable here](https://developer.apple.com/terms/) this ruling is even broader:
|
|
207
261
|
|
|
@@ -217,39 +271,41 @@ This is not necessarily the case for `updateDialog`, since it won't force the us
|
|
|
217
271
|
|
|
218
272
|
## Releasing Updates
|
|
219
273
|
|
|
220
|
-
Once your app
|
|
274
|
+
Once your app is configured and distributed to your users, and you have made some JS or asset changes, it's time to release them. The recommended way to release them is using the `release-react` command in the App Center CLI, which will bundle your JavaScript files, asset files, and release the update to the CodePush server.
|
|
275
|
+
|
|
276
|
+
*NOTE: Before you can start releasing updates, please log into App Center by running the `appcenter login` command.*
|
|
221
277
|
|
|
222
|
-
In it's most basic form, this command only requires
|
|
278
|
+
In it's the most basic form, this command only requires one parameter: your owner name + "/" + app name.
|
|
223
279
|
|
|
224
280
|
```shell
|
|
225
|
-
|
|
281
|
+
appcenter codepush release-react -a <ownerName>/<appName>
|
|
226
282
|
|
|
227
|
-
|
|
228
|
-
|
|
283
|
+
appcenter codepush release-react -a <ownerName>/MyApp-iOS
|
|
284
|
+
appcenter codepush release-react -a <ownerName>/MyApp-Android
|
|
229
285
|
```
|
|
230
286
|
|
|
231
287
|
The `release-react` command enables such a simple workflow because it provides many sensible defaults (like generating a release bundle, assuming your app's entry file on iOS is either `index.ios.js` or `index.js`). However, all of these defaults can be customized to allow incremental flexibility as necessary, which makes it a good fit for most scenarios.
|
|
232
288
|
|
|
233
289
|
```shell
|
|
234
290
|
# Release a mandatory update with a changelog
|
|
235
|
-
|
|
291
|
+
appcenter codepush release-react -a <ownerName>/MyApp-iOS -m --description "Modified the header color"
|
|
236
292
|
|
|
237
293
|
# Release an update for an app that uses a non-standard entry file name, and also capture
|
|
238
294
|
# the sourcemap file generated by react-native bundle
|
|
239
|
-
|
|
295
|
+
appcenter codepush release-react -a <ownerName>/MyApp-iOS --entry-file MyApp.js --sourcemap-output ../maps/MyApp.map
|
|
240
296
|
|
|
241
297
|
# Release a dev Android build to just 1/4 of your end users
|
|
242
|
-
|
|
298
|
+
appcenter codepush release-react -a <ownerName>/MyApp-Android --rollout 25 --development true
|
|
243
299
|
|
|
244
300
|
# Release an update that targets users running any 1.1.* binary, as opposed to
|
|
245
301
|
# limiting the update to exact version name in the build.gradle file
|
|
246
|
-
|
|
302
|
+
appcenter codepush release-react -a <ownerName>/MyApp-Android --target-binary-version "~1.1.0"
|
|
247
303
|
|
|
248
304
|
```
|
|
249
305
|
|
|
250
306
|
The CodePush client supports differential updates, so even though you are releasing your JS bundle and assets on every update, your end users will only actually download the files they need. The service handles this automatically so that you can focus on creating awesome apps and we can worry about optimizing end user downloads.
|
|
251
307
|
|
|
252
|
-
For more details about how the `release-react` command works, as well as the various parameters it exposes, refer to the [CLI docs](https://github.com/
|
|
308
|
+
For more details about how the `release-react` command works, as well as the various parameters it exposes, refer to the [CLI docs](https://github.com/microsoft/code-push/tree/v3.0.1/cli#releasing-updates-react-native). Additionally, if you would prefer to handle running the `react-native bundle` command yourself, and therefore, want an even more flexible solution than `release-react`, refer to the [`release` command](https://github.com/microsoft/code-push/tree/v3.0.1/cli#releasing-updates-general) for more details.
|
|
253
309
|
|
|
254
310
|
If you run into any issues, or have any questions/comments/feedback, you can ping us within the [#code-push](https://discord.gg/0ZcbPKXt5bWxFdFu) channel on Reactiflux, [e-mail us](mailto:codepushfeed@microsoft.com) and/or check out the [troubleshooting](#debugging--troubleshooting) details below.
|
|
255
311
|
|
|
@@ -259,19 +315,19 @@ If you run into any issues, or have any questions/comments/feedback, you can pin
|
|
|
259
315
|
|
|
260
316
|
In our [getting started](#getting-started) docs, we illustrated how to configure the CodePush plugin using a specific deployment key. However, in order to effectively test your releases, it is critical that you leverage the `Staging` and `Production` deployments that are auto-generated when you first created your CodePush app (or any custom deployments you may have created). This way, you never release an update to your end users that you haven't been able to validate yourself.
|
|
261
317
|
|
|
262
|
-
*NOTE: Our client-side rollback feature can help unblock users after installing a release that resulted in a crash, and server-side rollbacks (i.e. `
|
|
318
|
+
*NOTE: Our client-side rollback feature can help unblock users after installing a release that resulted in a crash, and server-side rollbacks (i.e. `appcenter codepush rollback`) allow you to prevent additional users from installing a bad release once it's been identified. However, it's obviously better if you can prevent an erroneous update from being broadly released in the first place.*
|
|
263
319
|
|
|
264
320
|
Taking advantage of the `Staging` and `Production` deployments allows you to achieve a workflow like the following (feel free to customize!):
|
|
265
321
|
|
|
266
|
-
1. Release a CodePush update to your `Staging` deployment using the `
|
|
322
|
+
1. Release a CodePush update to your `Staging` deployment using the `appcenter codepush release-react` command (or `appcenter codepush release` if you need more control)
|
|
267
323
|
|
|
268
324
|
2. Run your staging/beta build of your app, sync the update from the server, and verify it works as expected
|
|
269
325
|
|
|
270
|
-
3. Promote the tested release from `Staging` to `Production` using the `
|
|
326
|
+
3. Promote the tested release from `Staging` to `Production` using the `appcenter codepush promote` command
|
|
271
327
|
|
|
272
328
|
4. Run your production/release build of your app, sync the update from the server and verify it works as expected
|
|
273
329
|
|
|
274
|
-
*NOTE: If you want to
|
|
330
|
+
*NOTE: If you want to take a more cautious approach, you can even choose to perform a "staged rollout" as part of #3, which allows you to mitigate additional potential risk with the update (like did your testing in #2 touch all possible devices/conditions?) by only making the production update available to a percentage of your users (for example `appcenter codepush promote -a <ownerName>/<appName> -s Staging -d Production -r 20`). Then, after waiting for a reasonable amount of time to see if any crash reports or customer feedback comes in, you can expand it to your entire audience by running `appcenter codepush patch -a <ownerName>/<appName> Production -r 100`.*
|
|
275
331
|
|
|
276
332
|
You'll notice that the above steps refer to a "staging build" and "production build" of your app. If your build process already generates distinct binaries per "environment", then you don't need to read any further, since swapping out CodePush deployment keys is just like handling environment-specific config for any other service your app uses (like Facebook). However, if you're looking for examples (**including demo projects**) on how to setup your build process to accommodate this, then refer to the following sections, depending on the platform(s) your app is targeting:
|
|
277
333
|
|
|
@@ -303,10 +359,10 @@ Since we recommend using the `Staging` deployment for pre-release testing of you
|
|
|
303
359
|
|
|
304
360
|
```javascript
|
|
305
361
|
// #1) Create your new deployment to hold releases of a specific app variant
|
|
306
|
-
|
|
362
|
+
appcenter codepush deployment add -a <ownerName>/<appName> test-variant-one
|
|
307
363
|
|
|
308
364
|
// #2) Target any new releases at that custom deployment
|
|
309
|
-
|
|
365
|
+
appcenter codepush release-react -a <ownerName>/<appName> -d test-variant-one
|
|
310
366
|
```
|
|
311
367
|
|
|
312
368
|
*NOTE: The total user count that is reported in your deployment's "Install Metrics" will take into account users that have "switched" from one deployment to another. For example, if your `Production` deployment currently reports having 1 total user, but you dynamically switch that user to `Staging`, then the `Production` deployment would report 0 total users, while `Staging` would report 1 (the user that just switched). This behavior allows you to accurately track your release adoption, even in the event of using a runtime-based deployment redirection solution.*
|
|
@@ -339,7 +395,7 @@ Additionally, if you're looking to get started with React Native + CodePush, and
|
|
|
339
395
|
|
|
340
396
|
The `sync` method includes a lot of diagnostic logging out-of-the-box, so if you're encountering an issue when using it, the best thing to try first is examining the output logs of your app. This will tell you whether the app is configured correctly (like can the plugin find your deployment key?), if the app is able to reach the server, if an available update is being discovered, if the update is being successfully downloaded/installed, etc. We want to continue improving the logging to be as intuitive/comprehensive as possible, so please [let us know](mailto:codepushfeed@microsoft.com) if you find it to be confusing or missing anything.
|
|
341
397
|
|
|
342
|
-
The simplest way to view these logs is to
|
|
398
|
+
The simplest way to view these logs is to add the flag `--debug` for each command. This will output a log stream that is filtered to just CodePush messages. This makes it easy to identify issues, without needing to use a platform-specific tool, or wade through a potentially high volume of logs.
|
|
343
399
|
|
|
344
400
|
<img width="540" alt="screen shot 2016-06-21 at 10 15 42 am" src="https://cloud.githubusercontent.com/assets/116461/16246973/838e2e98-37bc-11e6-9649-685f39e325a0.png">
|
|
345
401
|
|
|
@@ -361,7 +417,7 @@ Now you'll be able to see CodePush logs in either debug or release mode, on both
|
|
|
361
417
|
|-----------------|-------------------|
|
|
362
418
|
| Compilation Error | Double-check that your version of React Native is [compatible](#supported-react-native-platforms) with the CodePush version you are using. |
|
|
363
419
|
| Network timeout / hang when calling `sync` or `checkForUpdate` in the iOS Simulator | Try resetting the simulator by selecting the `Simulator -> Reset Content and Settings..` menu item, and then re-running your app. |
|
|
364
|
-
| Server responds with a `404` when calling `sync` or `checkForUpdate` | Double-check that the deployment key you added to your `Info.plist` (iOS), `build.gradle` (Android) or that you're passing to `sync`/`checkForUpdate`, is in fact correct. You can run `
|
|
420
|
+
| Server responds with a `404` when calling `sync` or `checkForUpdate` | Double-check that the deployment key you added to your `Info.plist` (iOS), `build.gradle` (Android) or that you're passing to `sync`/`checkForUpdate`, is in fact correct. You can run `appcenter codepush deployment list <ownerName>/<appName> --displayKeys` to view the correct keys for your app deployments. |
|
|
365
421
|
| Update not being discovered | Double-check that the version of your running app (like `1.0.0`) matches the version you specified when releasing the update to CodePush. Additionally, make sure that you are releasing to the same deployment that your app is configured to sync with. |
|
|
366
422
|
| Update not being displayed after restart | If you're not calling `sync` on app start (like within `componentDidMount` of your root component), then you need to explicitly call `notifyApplicationReady` on app start, otherwise, the plugin will think your update failed and roll it back. |
|
|
367
423
|
| I've released an update for iOS but my Android app also shows an update and it breaks it | Be sure you have different deployment keys for each platform in order to receive updates correctly |
|
|
@@ -372,7 +428,7 @@ Now you'll be able to see CodePush logs in either debug or release mode, on both
|
|
|
372
428
|
|
|
373
429
|
In addition to being able to use the CodePush CLI to "manually" release updates, we believe that it's important to create a repeatable and sustainable solution for contiously delivering updates to your app. That way, it's simple enough for you and/or your team to create and maintain the rhythm of performing agile deployments. In order to assist with seting up a CodePush-based CD pipeline, refer to the following integrations with various CI servers:
|
|
374
430
|
|
|
375
|
-
* [Visual Studio Team Services](https://marketplace.visualstudio.com/items?itemName=ms-vsclient.code-push) - *NOTE: VSTS also has extensions for publishing to [HockeyApp](https://marketplace.visualstudio.com/items?itemName=ms.hockeyapp) and the [Google Play](https://github.com/
|
|
431
|
+
* [Visual Studio Team Services](https://marketplace.visualstudio.com/items?itemName=ms-vsclient.code-push) - *NOTE: VSTS also has extensions for publishing to [HockeyApp](https://marketplace.visualstudio.com/items?itemName=ms.hockeyapp) and the [Google Play](https://github.com/microsoft/google-play-vsts-extension) store, so it provides a pretty great mobile CD solution in general.*
|
|
376
432
|
* [Travis CI](https://github.com/mondora/code-push-travis-cli)
|
|
377
433
|
|
|
378
434
|
Additionally, if you'd like more details of what a complete mobile CI/CD workflow can look like, which includes CodePush, check out this [excellent article](https://zeemee.engineering/zeemee-engineering-and-the-quest-for-the-holy-mobile-dev-grail-1310be4953d1#.zfwaxtbco) by the [ZeeMee engineering team](https://zeemee.engineering).
|
|
@@ -20,6 +20,7 @@ import org.json.JSONObject;
|
|
|
20
20
|
import java.io.File;
|
|
21
21
|
import java.util.ArrayList;
|
|
22
22
|
import java.util.List;
|
|
23
|
+
import java.lang.reflect.Method;
|
|
23
24
|
|
|
24
25
|
public class CodePush implements ReactPackage {
|
|
25
26
|
|
|
@@ -77,6 +78,12 @@ public class CodePush implements ReactPackage {
|
|
|
77
78
|
|
|
78
79
|
mCurrentInstance = this;
|
|
79
80
|
|
|
81
|
+
String publicKeyFromStrings = getCustomPropertyFromStringsIfExist("PublicKey");
|
|
82
|
+
if (publicKeyFromStrings != null) mPublicKey = publicKeyFromStrings;
|
|
83
|
+
|
|
84
|
+
String serverUrlFromStrings = getCustomPropertyFromStringsIfExist("ServerUrl");
|
|
85
|
+
if (serverUrlFromStrings != null) mServerUrl = serverUrlFromStrings;
|
|
86
|
+
|
|
80
87
|
clearDebugCacheIfNeeded(null);
|
|
81
88
|
initializeUpdateAfterRestart();
|
|
82
89
|
}
|
|
@@ -120,20 +127,50 @@ public class CodePush implements ReactPackage {
|
|
|
120
127
|
return publicKey;
|
|
121
128
|
}
|
|
122
129
|
|
|
123
|
-
|
|
124
|
-
|
|
130
|
+
private String getCustomPropertyFromStringsIfExist(String propertyName) {
|
|
131
|
+
String property;
|
|
132
|
+
|
|
133
|
+
String packageName = mContext.getPackageName();
|
|
134
|
+
int resId = mContext.getResources().getIdentifier("CodePush" + propertyName, "string", packageName);
|
|
135
|
+
|
|
136
|
+
if (resId != 0) {
|
|
137
|
+
property = mContext.getString(resId);
|
|
138
|
+
|
|
139
|
+
if (!property.isEmpty()) {
|
|
140
|
+
return property;
|
|
141
|
+
} else {
|
|
142
|
+
CodePushUtils.log("Specified " + propertyName + " is empty");
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
return null;
|
|
147
|
+
}
|
|
125
148
|
|
|
126
|
-
|
|
127
|
-
//
|
|
149
|
+
private boolean isLiveReloadEnabled(ReactInstanceManager instanceManager) {
|
|
150
|
+
// Use instanceManager for checking if we use LiveReload mode. In this case we should not remove ReactNativeDevBundle.js file
|
|
151
|
+
// because we get error with trying to get this after reloading. Issue: https://github.com/microsoft/react-native-code-push/issues/1272
|
|
128
152
|
if (instanceManager != null) {
|
|
129
153
|
DevSupportManager devSupportManager = instanceManager.getDevSupportManager();
|
|
130
154
|
if (devSupportManager != null) {
|
|
131
155
|
DevInternalSettings devInternalSettings = (DevInternalSettings)devSupportManager.getDevSettings();
|
|
132
|
-
|
|
156
|
+
Method[] methods = devInternalSettings.getClass().getMethods();
|
|
157
|
+
for (Method m : methods) {
|
|
158
|
+
if (m.getName().equals("isReloadOnJSChangeEnabled")) {
|
|
159
|
+
try {
|
|
160
|
+
return (boolean) m.invoke(devInternalSettings);
|
|
161
|
+
} catch (Exception x) {
|
|
162
|
+
return false;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
}
|
|
133
166
|
}
|
|
134
167
|
}
|
|
135
168
|
|
|
136
|
-
|
|
169
|
+
return false;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
public void clearDebugCacheIfNeeded(ReactInstanceManager instanceManager) {
|
|
173
|
+
if (mIsDebugMode && mSettingsManager.isPendingUpdate(null) && !isLiveReloadEnabled(instanceManager)) {
|
|
137
174
|
// This needs to be kept in sync with https://github.com/facebook/react-native/blob/master/ReactAndroid/src/main/java/com/facebook/react/devsupport/DevSupportManager.java#L78
|
|
138
175
|
File cachedDevBundle = new File(mContext.getFilesDir(), "ReactNativeDevBundle.js");
|
|
139
176
|
if (cachedDevBundle.exists()) {
|
|
@@ -163,7 +200,7 @@ public class CodePush implements ReactPackage {
|
|
|
163
200
|
String packageName = this.mContext.getPackageName();
|
|
164
201
|
int codePushApkBuildTimeId = this.mContext.getResources().getIdentifier(CodePushConstants.CODE_PUSH_APK_BUILD_TIME_KEY, "string", packageName);
|
|
165
202
|
// replace double quotes needed for correct restoration of long value from strings.xml
|
|
166
|
-
// https://github.com/
|
|
203
|
+
// https://github.com/microsoft/cordova-plugin-code-push/issues/264
|
|
167
204
|
String codePushApkBuildTime = this.mContext.getResources().getString(codePushApkBuildTimeId).replaceAll("\"","");
|
|
168
205
|
return Long.parseLong(codePushApkBuildTime);
|
|
169
206
|
} catch (Exception e) {
|
|
File without changes
|