Skip to content

Commit

Permalink
Enable CodePush for react-native-windows v0.50+
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
rozele committed Oct 19, 2017
1 parent a585cbb commit afcfa97
Show file tree
Hide file tree
Showing 5 changed files with 149 additions and 19 deletions.
8 changes: 4 additions & 4 deletions docs/setup-windows.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,14 @@ Once you've acquired the CodePush plugin, you need to integrate it into the Visu

### 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#
...
// 1. Import the CodePush namespace
using CodePush.ReactNative;
...
class AppReactPage : ReactPage
class MainReactNativeHost : ReactNativeHost
{
// 2. Declare a private instance variable for the CodePushModule instance.
private CodePushReactPackage codePushReactPackage;
Expand All @@ -38,7 +38,7 @@ class AppReactPage : ReactPage
// 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
// deployment key, you can run "code-push deployment ls <appName> -k" to retrieve it.
public override string JavaScriptBundleFile
protected override string JavaScriptBundleFile
{
get
{
Expand All @@ -48,7 +48,7 @@ class AppReactPage : ReactPage
}

// 4. Add the codePushReactPackage instance to the list of existing packages.
public override List<IReactPackage> Packages
protected override List<IReactPackage> Packages
{
get
{
Expand Down
78 changes: 78 additions & 0 deletions windows/.gitignore
Original file line number Diff line number Diff line change
@@ -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 changes: 8 additions & 0 deletions windows/.npmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Make sure we don't publish build artifacts to NPM
ARM/
Debug/
x64/
x86/
bin/
obj/
.vs/
15 changes: 3 additions & 12 deletions windows/CodePush.Shared/CodePushNativeModule.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Threading;
using System.Threading.Tasks;
#if WINDOWS_UWP
using Windows.Web.Http;
Expand Down Expand Up @@ -312,17 +313,7 @@ internal async Task LoadBundleAsync()
{
// #1) Get the private ReactInstanceManager, which is what includes
// the logic to reload the current React context.
FieldInfo info = typeof(ReactPage)
.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
var reactInstanceManager = _codePush.ReactInstanceManager;

// #2) Update the locally stored JS bundle file path
Type reactInstanceManagerType = typeof(ReactInstanceManager);
Expand All @@ -332,7 +323,7 @@ internal async Task LoadBundleAsync()
.SetValue(reactInstanceManager, latestJSBundleFile);

// #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));
}
}
}
59 changes: 56 additions & 3 deletions windows/CodePush.Shared/CodePushReactPackage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using ReactNative.UIManager;
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Threading.Tasks;


Expand All @@ -20,10 +21,47 @@ public sealed class CodePushReactPackage : IReactPackage
internal bool NeedToReportRollback { get; set; } = false;
internal bool DidUpdate { 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; }
#pragma warning restore CS0618 // Keeping for backward compatibility
internal ReactNativeHost Host { 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)
#pragma warning restore CS0618 // Keeping for backward compatibility
{
AppVersion = CodePushUtils.GetAppVersion();
DeploymentKey = deploymentKey;
Expand All @@ -38,7 +76,22 @@ public CodePushReactPackage(string deploymentKey, ReactPage mainPage)
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()
{
return new List<Type>();
Expand Down Expand Up @@ -110,7 +163,7 @@ public async Task<string> GetJavaScriptBundleFileAsync(string assetsBundleFileNa
{
// The binary version is newer.
DidUpdate = false;
if (!MainPage.UseDeveloperSupport || !AppVersion.Equals(packageAppVersion))
if (!UseDeveloperSupport || !AppVersion.Equals(packageAppVersion))
{
await ClearUpdatesAsync().ConfigureAwait(false);
}
Expand Down Expand Up @@ -147,7 +200,7 @@ internal void InitializeUpdateAfterRestart()
{
DidUpdate = true;
// Clear the React dev bundle cache so that new updates can be loaded.
if (MainPage.UseDeveloperSupport)
if (UseDeveloperSupport)
{
FileUtils.ClearReactDevBundleCacheAsync().Wait();
}
Expand Down

0 comments on commit afcfa97

Please sign in to comment.