Skip to content
This repository was archived by the owner on May 20, 2025. It is now read-only.

Commit cf36d1c

Browse files
rozelesergey-akhalkov
authored andcommitted
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.
1 parent cccdc1c commit cf36d1c

File tree

5 files changed

+149
-19
lines changed

5 files changed

+149
-19
lines changed

docs/setup-windows.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,14 @@ Once you've acquired the CodePush plugin, you need to integrate it into the Visu
2222

2323
### Plugin Configuration (Windows)
2424

25-
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:
25+
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:
2626

2727
```c#
2828
...
2929
// 1. Import the CodePush namespace
3030
using CodePush.ReactNative;
3131
...
32-
class AppReactPage : ReactPage
32+
class MainReactNativeHost : ReactNativeHost
3333
{
3434
// 2. Declare a private instance variable for the CodePushModule instance.
3535
private CodePushReactPackage codePushReactPackage;
@@ -38,7 +38,7 @@ class AppReactPage : ReactPage
3838
// specifying the right deployment key, then use it to return the bundle URL from
3939
// CodePush instead of statically from the binary. If you don't already have your
4040
// deployment key, you can run "code-push deployment ls <appName> -k" to retrieve it.
41-
public override string JavaScriptBundleFile
41+
protected override string JavaScriptBundleFile
4242
{
4343
get
4444
{
@@ -48,7 +48,7 @@ class AppReactPage : ReactPage
4848
}
4949

5050
// 4. Add the codePushReactPackage instance to the list of existing packages.
51-
public override List<IReactPackage> Packages
51+
protected override List<IReactPackage> Packages
5252
{
5353
get
5454
{

windows/.gitignore

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
*AppPackages*
2+
*BundleArtifacts*
3+
*ReactAssets*
4+
5+
#OS junk files
6+
[Tt]humbs.db
7+
*.DS_Store
8+
9+
#Visual Studio files
10+
*.[Oo]bj
11+
*.user
12+
*.aps
13+
*.pch
14+
*.vspscc
15+
*.vssscc
16+
*_i.c
17+
*_p.c
18+
*.ncb
19+
*.suo
20+
*.tlb
21+
*.tlh
22+
*.bak
23+
*.[Cc]ache
24+
*.ilk
25+
*.log
26+
*.lib
27+
*.sbr
28+
*.sdf
29+
*.opensdf
30+
*.opendb
31+
*.unsuccessfulbuild
32+
ipch/
33+
[Oo]bj/
34+
[Bb]in
35+
[Dd]ebug*/
36+
[Rr]elease*/
37+
Ankh.NoLoad
38+
39+
#MonoDevelop
40+
*.pidb
41+
*.userprefs
42+
43+
#Tooling
44+
_ReSharper*/
45+
*.resharper
46+
[Tt]est[Rr]esult*
47+
*.sass-cache
48+
49+
#Project files
50+
[Bb]uild/
51+
52+
#Subversion files
53+
.svn
54+
55+
# Office Temp Files
56+
~$*
57+
58+
# vim Temp Files
59+
*~
60+
61+
#NuGet
62+
packages/
63+
*.nupkg
64+
65+
#ncrunch
66+
*ncrunch*
67+
*crunch*.local.xml
68+
69+
# visual studio database projects
70+
*.dbmdl
71+
72+
#Test files
73+
*.testsettings
74+
75+
#Other files
76+
*.DotSettings
77+
.vs/
78+
*project.lock.json

windows/.npmignore

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# Make sure we don't publish build artifacts to NPM
2+
ARM/
3+
Debug/
4+
x64/
5+
x86/
6+
bin/
7+
obj/
8+
.vs/

windows/CodePush.Shared/CodePushNativeModule.cs

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
using System.Collections.Generic;
77
using System.IO;
88
using System.Reflection;
9+
using System.Threading;
910
using System.Threading.Tasks;
1011
#if WINDOWS_UWP
1112
using Windows.Web.Http;
@@ -312,17 +313,7 @@ internal async Task LoadBundleAsync()
312313
{
313314
// #1) Get the private ReactInstanceManager, which is what includes
314315
// the logic to reload the current React context.
315-
FieldInfo info = typeof(ReactPage)
316-
.GetField("_reactInstanceManager", BindingFlags.NonPublic | BindingFlags.Instance);
317-
#if WINDOWS_UWP
318-
var reactInstanceManager = (ReactInstanceManager)typeof(ReactPage)
319-
.GetField("_reactInstanceManager", BindingFlags.NonPublic | BindingFlags.Instance)
320-
.GetValue(_codePush.MainPage);
321-
#else
322-
var reactInstanceManager = ((Lazy<IReactInstanceManager>)typeof(ReactPage)
323-
.GetField("_reactInstanceManager", BindingFlags.NonPublic | BindingFlags.Instance)
324-
.GetValue(_codePush.MainPage)).Value as ReactInstanceManager;
325-
#endif
316+
var reactInstanceManager = _codePush.ReactInstanceManager;
326317

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

334325
// #3) Get the context creation method and fire it on the UI thread (which RN enforces)
335-
Context.RunOnDispatcherQueueThread(reactInstanceManager.RecreateReactContextInBackground);
326+
Context.RunOnDispatcherQueueThread(() => reactInstanceManager.RecreateReactContextAsync(CancellationToken.None));
336327
}
337328
}
338329
}

windows/CodePush.Shared/CodePushReactPackage.cs

Lines changed: 56 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
using ReactNative.UIManager;
66
using System;
77
using System.Collections.Generic;
8+
using System.Reflection;
89
using System.Threading.Tasks;
910

1011

@@ -20,10 +21,47 @@ public sealed class CodePushReactPackage : IReactPackage
2021
internal bool NeedToReportRollback { get; set; } = false;
2122
internal bool DidUpdate { get; private set; } = false;
2223
internal bool IsRunningBinaryVersion { get; private set; } = false;
24+
#pragma warning disable CS0618 // Keeping for backward compatibility
2325
internal ReactPage MainPage { get; private set; }
26+
#pragma warning restore CS0618 // Keeping for backward compatibility
27+
internal ReactNativeHost Host { get; private set; }
2428
internal UpdateManager UpdateManager { get; private set; }
2529

30+
internal ReactInstanceManager ReactInstanceManager
31+
{
32+
get
33+
{
34+
if (Host != null)
35+
{
36+
return Host.ReactInstanceManager;
37+
}
38+
39+
#if WINDOWS_UWP
40+
#pragma warning disable CS0618 // Keeping for backward compatibility
41+
return (ReactInstanceManager)typeof(ReactPage)
42+
#pragma warning restore CS0618 // Keeping for backward compatibility
43+
.GetField("_reactInstanceManager", BindingFlags.NonPublic | BindingFlags.Instance)
44+
.GetValue(MainPage);
45+
#else
46+
return ((Lazy<ReactInstanceManager>)typeof(ReactPage)
47+
.GetField("_reactInstanceManager", BindingFlags.NonPublic | BindingFlags.Instance)
48+
.GetValue(MainPage)).Value as ReactInstanceManager;
49+
#endif
50+
}
51+
}
52+
53+
internal bool UseDeveloperSupport
54+
{
55+
get
56+
{
57+
return Host?.UseDeveloperSupport ?? MainPage.UseDeveloperSupport;
58+
}
59+
}
60+
61+
62+
#pragma warning disable CS0618 // Keeping for backward compatibility
2663
public CodePushReactPackage(string deploymentKey, ReactPage mainPage)
64+
#pragma warning restore CS0618 // Keeping for backward compatibility
2765
{
2866
AppVersion = CodePushUtils.GetAppVersion();
2967
DeploymentKey = deploymentKey;
@@ -38,7 +76,22 @@ public CodePushReactPackage(string deploymentKey, ReactPage mainPage)
3876
CurrentInstance = this;
3977
}
4078

41-
#region Public methods
79+
public CodePushReactPackage(string deploymentKey, ReactNativeHost host)
80+
{
81+
AppVersion = CodePushUtils.GetAppVersion();
82+
DeploymentKey = deploymentKey;
83+
Host = host;
84+
UpdateManager = new UpdateManager();
85+
86+
if (CurrentInstance != null)
87+
{
88+
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.");
89+
}
90+
91+
CurrentInstance = this;
92+
}
93+
94+
#region Public methods
4295
public IReadOnlyList<Type> CreateJavaScriptModulesConfig()
4396
{
4497
return new List<Type>();
@@ -110,7 +163,7 @@ public async Task<string> GetJavaScriptBundleFileAsync(string assetsBundleFileNa
110163
{
111164
// The binary version is newer.
112165
DidUpdate = false;
113-
if (!MainPage.UseDeveloperSupport || !AppVersion.Equals(packageAppVersion))
166+
if (!UseDeveloperSupport || !AppVersion.Equals(packageAppVersion))
114167
{
115168
await ClearUpdatesAsync().ConfigureAwait(false);
116169
}
@@ -147,7 +200,7 @@ internal void InitializeUpdateAfterRestart()
147200
{
148201
DidUpdate = true;
149202
// Clear the React dev bundle cache so that new updates can be loaded.
150-
if (MainPage.UseDeveloperSupport)
203+
if (UseDeveloperSupport)
151204
{
152205
FileUtils.ClearReactDevBundleCacheAsync().Wait();
153206
}

0 commit comments

Comments
 (0)