Skip to content
This repository has been archived by the owner on Oct 7, 2024. It is now read-only.

Commit

Permalink
Support RN 0.34 (microsoft#557)
Browse files Browse the repository at this point in the history
* Upgrade example app to RN 0.34.1
* Fix Android reflection logic to support RN 0.34 (as reported in microsoft#536), while maintaining backward compatibility
* Bump package.json and update supported RN versions in README
  • Loading branch information
Richard Hua authored Oct 6, 2016
1 parent b8fc75f commit 22d2a14
Show file tree
Hide file tree
Showing 6 changed files with 64 additions and 28 deletions.
8 changes: 4 additions & 4 deletions Examples/CodePushDemoApp/.flowconfig
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[ignore]

# We fork some components by platform.
.*/*.android.js
.*/*[.]android.js

# Ignore templates with `@flow` in header
.*/local-cli/generator.*
Expand Down Expand Up @@ -48,11 +48,11 @@ suppress_type=$FlowIssue
suppress_type=$FlowFixMe
suppress_type=$FixMe

suppress_comment=\\(.\\|\n\\)*\\$FlowFixMe\\($\\|[^(]\\|(\\(>=0\\.\\(30\\|[1-2][0-9]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\)
suppress_comment=\\(.\\|\n\\)*\\$FlowIssue\\((\\(>=0\\.\\(30\\|1[0-9]\\|[1-2][0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\)?:? #[0-9]+
suppress_comment=\\(.\\|\n\\)*\\$FlowFixMe\\($\\|[^(]\\|(\\(>=0\\.\\(3[0-2]\\|[1-2][0-9]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\)
suppress_comment=\\(.\\|\n\\)*\\$FlowIssue\\((\\(>=0\\.\\(3[0-2]\\|1[0-9]\\|[1-2][0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\)?:? #[0-9]+
suppress_comment=\\(.\\|\n\\)*\\$FlowFixedInNextDeploy

unsafe.enable_getters_and_setters=true

[version]
^0.30.0
^0.32.0
Original file line number Diff line number Diff line change
Expand Up @@ -616,7 +616,7 @@
"$(inherited)",
);
INFOPLIST_FILE = CodePushDemoAppTests/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 8.2;
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_NAME = "$(TARGET_NAME)";
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/CodePushDemoApp.app/CodePushDemoApp";
Expand All @@ -629,7 +629,7 @@
BUNDLE_LOADER = "$(TEST_HOST)";
COPY_PHASE_STRIP = NO;
INFOPLIST_FILE = CodePushDemoAppTests/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 8.2;
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_NAME = "$(TARGET_NAME)";
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/CodePushDemoApp.app/CodePushDemoApp";
Expand All @@ -640,6 +640,7 @@
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CURRENT_PROJECT_VERSION = 1;
DEAD_CODE_STRIPPING = NO;
HEADER_SEARCH_PATHS = (
"$(inherited)",
Expand All @@ -655,13 +656,15 @@
"-lc++",
);
PRODUCT_NAME = CodePushDemoApp;
VERSIONING_SYSTEM = "apple-generic";
};
name = Debug;
};
13B07F951A680F5B00A75B9A /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CURRENT_PROJECT_VERSION = 1;
HEADER_SEARCH_PATHS = (
"$(inherited)",
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
Expand All @@ -676,6 +679,7 @@
"-lc++",
);
PRODUCT_NAME = CodePushDemoApp;
VERSIONING_SYSTEM = "apple-generic";
};
name = Release;
};
Expand Down Expand Up @@ -718,7 +722,7 @@
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
"$(SRCROOT)/../node_modules/react-native/React/**",
);
IPHONEOS_DEPLOYMENT_TARGET = 7.0;
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
Expand Down Expand Up @@ -758,7 +762,7 @@
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
"$(SRCROOT)/../node_modules/react-native/React/**",
);
IPHONEOS_DEPLOYMENT_TARGET = 7.0;
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
VALIDATE_PRODUCT = YES;
Expand Down
2 changes: 1 addition & 1 deletion Examples/CodePushDemoApp/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
"dependencies": {
"babel-preset-react-native-stage-0": "1.0.1",
"react": "15.3.1",
"react-native": "0.33.0",
"react-native": "0.34.1",
"react-native-code-push": "file:../../"
}
}
9 changes: 5 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,10 @@ We try our best to maintain backwards compatability of our plugin with previous
| v0.14 | v1.3.0 *(introduced Android support)* |
| v0.15-v0.18 | v1.4.0-v1.6.0 *(introduced iOS asset support)* |
| v0.19-v0.28 | v1.7.0+ *(introduced Android asset support)* |
| v0.29-v0.31 | v1.13.0+ *(RN refactored native hosting code)* |
| v0.32-v0.33 | v1.14.6+ *(RN refactored native hosting code)* |
| v0.34+ | TBD :) 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.
| v0.29-v0.30 | v1.13.0+ *(RN refactored native hosting code)* |
| v0.31-v0.33 | v1.14.6+ *(RN refactored native hosting code)* |
| v0.34 | v1.15.0+ *(RN refactored native hosting code)* |
| v0.35+ | TBD :) 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.

## Supported Components

Expand Down Expand Up @@ -83,7 +84,7 @@ Once you've followed the general-purpose ["getting started"](http://codepush.too
npm install --save react-native-code-push@latest
```

As with all other React Native plugins, the integration experience is different for iOS and Android, so perform the following setup steps depending on which platform(s) you are targeting. Note, if you are targeting both platforms it is recommended to create separate CodePush applications for each platform.
As with all other React Native plugins, the integration experience is different for iOS and Android, so perform the following setup steps depending on which platform(s) you are targeting. Note, if you are targeting both platforms it is recommended to create separate CodePush applications for each platform.

If you want to see how other projects have integrated with CodePush, you can check out the excellent [example apps](#example-apps--starters) provided by the community. Additionally, if you'd like to quickly familiarize yourself with CodePush + React Native, you can check out the awesome getting started videos produced by [Bilal Budhani](https://www.youtube.com/watch?v=uN0FRWk-YW8&feature=youtu.be) and/or [Deepak Sisodiya ](https://www.youtube.com/watch?v=f6I9y7V-Ibk).

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,49 @@ public void run() {
});
}

// Use reflection to find and set the appropriate fields on ReactInstanceManager. See #556 for a proposal for a less brittle way
// to approach this.
private void setJSBundle(ReactInstanceManager instanceManager, String latestJSBundleFile) throws NoSuchFieldException, IllegalAccessException {
try {
Field bundleLoaderField = instanceManager.getClass().getDeclaredField("mBundleLoader");
Class<?> jsBundleLoaderClass = Class.forName("com.facebook.react.cxxbridge.JSBundleLoader");
Method createFileLoaderMethod = null;

Method[] methods = jsBundleLoaderClass.getDeclaredMethods();
for (Method method : methods) {
if (method.getName() == "createFileLoader") {
createFileLoaderMethod = method;
break;
}
}

if (createFileLoaderMethod == null) {
throw new NoSuchMethodException("Could not find a recognized 'createFileLoader' method");
}

int numParameters = createFileLoaderMethod.getGenericParameterTypes().length;
Object latestJSBundleLoader;

if (numParameters == 1) {
// RN >= v0.34
latestJSBundleLoader = createFileLoaderMethod.invoke(jsBundleLoaderClass, latestJSBundleFile);
} else if (numParameters == 2) {
// RN >= v0.31 && RN < v0.34
latestJSBundleLoader = createFileLoaderMethod.invoke(jsBundleLoaderClass, getReactApplicationContext(), latestJSBundleFile);
} else {
throw new NoSuchMethodException("Could not find a recognized 'createFileLoader' method");
}

bundleLoaderField.setAccessible(true);
bundleLoaderField.set(instanceManager, latestJSBundleLoader);
} catch (Exception e) {
// RN < v0.31
Field jsBundleField = instanceManager.getClass().getDeclaredField("mJSBundleFile");
jsBundleField.setAccessible(true);
jsBundleField.set(instanceManager, latestJSBundleFile);
}
}

private void loadBundle() {
mCodePush.clearDebugCacheIfNeeded();
try {
Expand All @@ -109,20 +152,7 @@ private void loadBundle() {
String latestJSBundleFile = mCodePush.getJSBundleFileInternal(mCodePush.getAssetsBundleFileName());

// #2) Update the locally stored JS bundle file path
try {
// RN >= v0.30
Field bundleLoaderField = instanceManager.getClass().getDeclaredField("mBundleLoader");
Class<?> jsBundleLoaderClass = Class.forName("com.facebook.react.cxxbridge.JSBundleLoader");
Method createFileLoaderMethod = jsBundleLoaderClass.getDeclaredMethod("createFileLoader", Context.class, String.class);
Object latestJSBundleLoader = createFileLoaderMethod.invoke(jsBundleLoaderClass, getReactApplicationContext(), latestJSBundleFile);
bundleLoaderField.setAccessible(true);
bundleLoaderField.set(instanceManager, latestJSBundleLoader);
} catch (Exception e) {
// RN <= v0.30
Field jsBundleField = instanceManager.getClass().getDeclaredField("mJSBundleFile");
jsBundleField.setAccessible(true);
jsBundleField.set(instanceManager, latestJSBundleFile);
}
setJSBundle(instanceManager, latestJSBundleFile);

// #3) Get the context creation method and fire it on the UI thread (which RN enforces)
final Method recreateMethod = instanceManager.getClass().getMethod("recreateReactContextInBackground");
Expand All @@ -147,6 +177,7 @@ public void run() {
}
}

// Use reflection to find the ReactInstanceManager. See #556 for a proposal for a less brittle way to approach this.
private ReactInstanceManager resolveInstanceManager() throws NoSuchFieldException, IllegalAccessException {
ReactInstanceManager instanceManager = CodePush.getReactInstanceManager();
if (instanceManager != null) {
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "react-native-code-push",
"version": "1.14.7-beta",
"version": "1.15.0-beta",
"description": "React Native plugin for the CodePush service",
"main": "CodePush.js",
"typings": "typings/react-native-code-push.d.ts",
Expand Down

0 comments on commit 22d2a14

Please sign in to comment.