Enable CodePush for react-native-windows v0.50+ (#1051)

In react-native-windows v0.50+, we added ReactNativeHost, which has better support for running React Native in the background as well as embedding React Native in other controls besides XAML Pages.
This commit is contained in:
Eric Rozell
2017-11-16 12:22:01 -05:00
committed by Sergey Akhalkov
parent cccdc1c2de
commit cf36d1cf25
5 changed files with 149 additions and 19 deletions

View File

@@ -22,14 +22,14 @@ Once you've acquired the CodePush plugin, you need to integrate it into the Visu
### Plugin Configuration (Windows) ### Plugin Configuration (Windows)
After installing the plugin, you need to configure your app to consult CodePush for the location of your JS bundle, since it will "take control" of managing the current and all future versions. To do this, update the `AppReactPage.cs` file to use CodePush via the following changes: After installing the plugin, you need to configure your app to consult CodePush for the location of your JS bundle, since it will "take control" of managing the current and all future versions. To do this, update the `MainReactNativeHost.cs` file to use CodePush via the following changes:
```c# ```c#
... ...
// 1. Import the CodePush namespace // 1. Import the CodePush namespace
using CodePush.ReactNative; using CodePush.ReactNative;
... ...
class AppReactPage : ReactPage class MainReactNativeHost : ReactNativeHost
{ {
// 2. Declare a private instance variable for the CodePushModule instance. // 2. Declare a private instance variable for the CodePushModule instance.
private CodePushReactPackage codePushReactPackage; private CodePushReactPackage codePushReactPackage;
@@ -38,7 +38,7 @@ class AppReactPage : ReactPage
// specifying the right deployment key, then use it to return the bundle URL from // specifying the right deployment key, then use it to return the bundle URL from
// CodePush instead of statically from the binary. If you don't already have your // CodePush instead of statically from the binary. If you don't already have your
// deployment key, you can run "code-push deployment ls <appName> -k" to retrieve it. // deployment key, you can run "code-push deployment ls <appName> -k" to retrieve it.
public override string JavaScriptBundleFile protected override string JavaScriptBundleFile
{ {
get get
{ {
@@ -48,7 +48,7 @@ class AppReactPage : ReactPage
} }
// 4. Add the codePushReactPackage instance to the list of existing packages. // 4. Add the codePushReactPackage instance to the list of existing packages.
public override List<IReactPackage> Packages protected override List<IReactPackage> Packages
{ {
get get
{ {

78
windows/.gitignore vendored Normal file
View File

@@ -0,0 +1,78 @@
*AppPackages*
*BundleArtifacts*
*ReactAssets*
#OS junk files
[Tt]humbs.db
*.DS_Store
#Visual Studio files
*.[Oo]bj
*.user
*.aps
*.pch
*.vspscc
*.vssscc
*_i.c
*_p.c
*.ncb
*.suo
*.tlb
*.tlh
*.bak
*.[Cc]ache
*.ilk
*.log
*.lib
*.sbr
*.sdf
*.opensdf
*.opendb
*.unsuccessfulbuild
ipch/
[Oo]bj/
[Bb]in
[Dd]ebug*/
[Rr]elease*/
Ankh.NoLoad
#MonoDevelop
*.pidb
*.userprefs
#Tooling
_ReSharper*/
*.resharper
[Tt]est[Rr]esult*
*.sass-cache
#Project files
[Bb]uild/
#Subversion files
.svn
# Office Temp Files
~$*
# vim Temp Files
*~
#NuGet
packages/
*.nupkg
#ncrunch
*ncrunch*
*crunch*.local.xml
# visual studio database projects
*.dbmdl
#Test files
*.testsettings
#Other files
*.DotSettings
.vs/
*project.lock.json

8
windows/.npmignore Normal file
View File

@@ -0,0 +1,8 @@
# Make sure we don't publish build artifacts to NPM
ARM/
Debug/
x64/
x86/
bin/
obj/
.vs/

View File

@@ -6,6 +6,7 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Reflection; using System.Reflection;
using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
#if WINDOWS_UWP #if WINDOWS_UWP
using Windows.Web.Http; using Windows.Web.Http;
@@ -312,17 +313,7 @@ namespace CodePush.ReactNative
{ {
// #1) Get the private ReactInstanceManager, which is what includes // #1) Get the private ReactInstanceManager, which is what includes
// the logic to reload the current React context. // the logic to reload the current React context.
FieldInfo info = typeof(ReactPage) var reactInstanceManager = _codePush.ReactInstanceManager;
.GetField("_reactInstanceManager", BindingFlags.NonPublic | BindingFlags.Instance);
#if WINDOWS_UWP
var reactInstanceManager = (ReactInstanceManager)typeof(ReactPage)
.GetField("_reactInstanceManager", BindingFlags.NonPublic | BindingFlags.Instance)
.GetValue(_codePush.MainPage);
#else
var reactInstanceManager = ((Lazy<IReactInstanceManager>)typeof(ReactPage)
.GetField("_reactInstanceManager", BindingFlags.NonPublic | BindingFlags.Instance)
.GetValue(_codePush.MainPage)).Value as ReactInstanceManager;
#endif
// #2) Update the locally stored JS bundle file path // #2) Update the locally stored JS bundle file path
Type reactInstanceManagerType = typeof(ReactInstanceManager); Type reactInstanceManagerType = typeof(ReactInstanceManager);
@@ -332,7 +323,7 @@ namespace CodePush.ReactNative
.SetValue(reactInstanceManager, latestJSBundleFile); .SetValue(reactInstanceManager, latestJSBundleFile);
// #3) Get the context creation method and fire it on the UI thread (which RN enforces) // #3) Get the context creation method and fire it on the UI thread (which RN enforces)
Context.RunOnDispatcherQueueThread(reactInstanceManager.RecreateReactContextInBackground); Context.RunOnDispatcherQueueThread(() => reactInstanceManager.RecreateReactContextAsync(CancellationToken.None));
} }
} }
} }

View File

@@ -5,6 +5,7 @@ using ReactNative.Modules.Core;
using ReactNative.UIManager; using ReactNative.UIManager;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Reflection;
using System.Threading.Tasks; using System.Threading.Tasks;
@@ -20,10 +21,47 @@ namespace CodePush.ReactNative
internal bool NeedToReportRollback { get; set; } = false; internal bool NeedToReportRollback { get; set; } = false;
internal bool DidUpdate { get; private set; } = false; internal bool DidUpdate { get; private set; } = false;
internal bool IsRunningBinaryVersion { get; private set; } = false; internal bool IsRunningBinaryVersion { get; private set; } = false;
#pragma warning disable CS0618 // Keeping for backward compatibility
internal ReactPage MainPage { get; private set; } internal ReactPage MainPage { get; private set; }
#pragma warning restore CS0618 // Keeping for backward compatibility
internal ReactNativeHost Host { get; private set; }
internal UpdateManager UpdateManager { get; private set; } internal UpdateManager UpdateManager { get; private set; }
internal ReactInstanceManager ReactInstanceManager
{
get
{
if (Host != null)
{
return Host.ReactInstanceManager;
}
#if WINDOWS_UWP
#pragma warning disable CS0618 // Keeping for backward compatibility
return (ReactInstanceManager)typeof(ReactPage)
#pragma warning restore CS0618 // Keeping for backward compatibility
.GetField("_reactInstanceManager", BindingFlags.NonPublic | BindingFlags.Instance)
.GetValue(MainPage);
#else
return ((Lazy<ReactInstanceManager>)typeof(ReactPage)
.GetField("_reactInstanceManager", BindingFlags.NonPublic | BindingFlags.Instance)
.GetValue(MainPage)).Value as ReactInstanceManager;
#endif
}
}
internal bool UseDeveloperSupport
{
get
{
return Host?.UseDeveloperSupport ?? MainPage.UseDeveloperSupport;
}
}
#pragma warning disable CS0618 // Keeping for backward compatibility
public CodePushReactPackage(string deploymentKey, ReactPage mainPage) public CodePushReactPackage(string deploymentKey, ReactPage mainPage)
#pragma warning restore CS0618 // Keeping for backward compatibility
{ {
AppVersion = CodePushUtils.GetAppVersion(); AppVersion = CodePushUtils.GetAppVersion();
DeploymentKey = deploymentKey; DeploymentKey = deploymentKey;
@@ -38,7 +76,22 @@ namespace CodePush.ReactNative
CurrentInstance = this; CurrentInstance = this;
} }
#region Public methods public CodePushReactPackage(string deploymentKey, ReactNativeHost host)
{
AppVersion = CodePushUtils.GetAppVersion();
DeploymentKey = deploymentKey;
Host = host;
UpdateManager = new UpdateManager();
if (CurrentInstance != null)
{
CodePushUtils.Log("More than one CodePush instance has been initialized. Please use the instance method codePush.getBundleUrlInternal() to get the correct bundleURL for a particular instance.");
}
CurrentInstance = this;
}
#region Public methods
public IReadOnlyList<Type> CreateJavaScriptModulesConfig() public IReadOnlyList<Type> CreateJavaScriptModulesConfig()
{ {
return new List<Type>(); return new List<Type>();
@@ -110,7 +163,7 @@ namespace CodePush.ReactNative
{ {
// The binary version is newer. // The binary version is newer.
DidUpdate = false; DidUpdate = false;
if (!MainPage.UseDeveloperSupport || !AppVersion.Equals(packageAppVersion)) if (!UseDeveloperSupport || !AppVersion.Equals(packageAppVersion))
{ {
await ClearUpdatesAsync().ConfigureAwait(false); await ClearUpdatesAsync().ConfigureAwait(false);
} }
@@ -147,7 +200,7 @@ namespace CodePush.ReactNative
{ {
DidUpdate = true; DidUpdate = true;
// Clear the React dev bundle cache so that new updates can be loaded. // Clear the React dev bundle cache so that new updates can be loaded.
if (MainPage.UseDeveloperSupport) if (UseDeveloperSupport)
{ {
FileUtils.ClearReactDevBundleCacheAsync().Wait(); FileUtils.ClearReactDevBundleCacheAsync().Wait();
} }