react-native-update 10.27.1 → 10.28.0

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.
@@ -22,14 +22,42 @@ def supportsNamespace() {
22
22
  return major >= 8
23
23
  }
24
24
 
25
+ def isExpoProject() {
26
+ def hasExpoModulesCore = rootProject.subprojects.any { it.name == 'expo-modules-core' }
27
+
28
+ def packageJsonFile = new File(rootProject.projectDir.parentFile, 'package.json')
29
+ def hasExpoDependency = false
30
+ if (packageJsonFile.exists()) {
31
+ def packageJson = new groovy.json.JsonSlurper().parseText(packageJsonFile.text)
32
+ hasExpoDependency = (packageJson.dependencies?.expo != null) ||
33
+ (packageJson.devDependencies?.expo != null)
34
+ }
35
+
36
+ return hasExpoModulesCore || hasExpoDependency
37
+ }
38
+
39
+ def expoProject = isExpoProject()
40
+
25
41
  apply plugin: 'com.android.library'
26
42
  if (isNewArchitectureEnabled()) {
27
43
  apply plugin: 'com.facebook.react'
28
44
  }
29
45
 
46
+ if (expoProject) {
47
+ group = 'expo.modules.pushy'
48
+ version = '1.0.0'
30
49
 
31
- android {
50
+ def expoModulesCorePlugin = new File(project(":expo-modules-core").projectDir.absolutePath, "ExpoModulesCorePlugin.gradle")
51
+ apply from: expoModulesCorePlugin
52
+ applyKotlinExpoModulesCorePlugin()
53
+ useCoreDependencies()
54
+ useExpoPublishing()
55
+ } else {
56
+ group = 'cn.reactnative.modules.update'
57
+ version = '1.0.0'
58
+ }
32
59
 
60
+ android {
33
61
  if (supportsNamespace()) {
34
62
  namespace "cn.reactnative.modules.update"
35
63
 
@@ -41,7 +69,6 @@ android {
41
69
  }
42
70
  compileSdkVersion safeExtGet('compileSdkVersion', 28)
43
71
  buildToolsVersion safeExtGet('buildToolsVersion', '28.0.3')
44
-
45
72
  defaultConfig {
46
73
  minSdkVersion safeExtGet('minSdkVersion', 16)
47
74
  targetSdkVersion safeExtGet('targetSdkVersion', 27)
@@ -50,6 +77,7 @@ android {
50
77
  consumerProguardFiles "proguard.pro"
51
78
  buildConfigField "boolean", "IS_NEW_ARCHITECTURE_ENABLED", isNewArchitectureEnabled().toString()
52
79
  }
80
+
53
81
  sourceSets {
54
82
  main {
55
83
  // let gradle pack the shared library into apk
@@ -59,6 +87,12 @@ android {
59
87
  } else {
60
88
  java.srcDirs += ['src/oldarch']
61
89
  }
90
+
91
+ if (expoProject) {
92
+ java.srcDirs += ['java/expo/modules/pushy']
93
+ } else {
94
+ java.exclude 'expo/modules/pushy/**'
95
+ }
62
96
  }
63
97
  }
64
98
 
@@ -70,6 +104,10 @@ android {
70
104
  resValue("string", "pushy_build_time", "0")
71
105
  }
72
106
  }
107
+
108
+ lintOptions {
109
+ abortOnError false
110
+ }
73
111
  }
74
112
 
75
113
  repositories {
@@ -0,0 +1,13 @@
1
+ package cn.reactnative.modules.update;
2
+
3
+ import androidx.annotation.Nullable;
4
+
5
+ public interface ReactNativeHostHandler {
6
+ @Nullable
7
+ String getJSBundleFile(boolean useDeveloperSupport);
8
+
9
+ @Nullable
10
+ String getBundleAssetName(boolean useDeveloperSupport);
11
+
12
+ void onWillCreateReactInstance(boolean useDeveloperSupport);
13
+ }
@@ -7,14 +7,11 @@ import android.content.pm.PackageManager;
7
7
  import android.os.Build;
8
8
  import android.os.Environment;
9
9
  import android.util.Log;
10
-
11
10
  import com.facebook.react.ReactInstanceManager;
12
-
13
11
  import java.util.HashMap;
14
12
  import java.util.Map;
15
13
  import java.util.concurrent.Executor;
16
14
  import java.util.concurrent.Executors;
17
-
18
15
  import java.io.File;
19
16
 
20
17
  public class UpdateContext {
@@ -176,6 +176,35 @@ public class UpdateModuleImpl {
176
176
  });
177
177
  }
178
178
 
179
+ public static void restartApp(final ReactApplicationContext mContext, Promise promise) {
180
+ UiThreadUtil.runOnUiThread(new Runnable() {
181
+ @Override
182
+ public void run() {
183
+ try {
184
+ final Context application = mContext.getApplicationContext();
185
+ ReactInstanceManager instanceManager = ((ReactApplication) application).getReactNativeHost().getReactInstanceManager();
186
+
187
+ instanceManager.recreateReactContextInBackground();
188
+ promise.resolve(true);
189
+
190
+ } catch (Throwable err) {
191
+ promise.reject("restartApp failed: "+err.getMessage());
192
+ Log.e("pushy", "restartApp failed", err);
193
+
194
+ final Activity currentActivity = mContext.getCurrentActivity();
195
+ if (currentActivity == null) {
196
+ return;
197
+ }
198
+ currentActivity.runOnUiThread(new Runnable() {
199
+ @Override
200
+ public void run() {
201
+ currentActivity.recreate();
202
+ }
203
+ });
204
+ }
205
+ }
206
+ });
207
+ }
179
208
 
180
209
  public static void setNeedUpdate(UpdateContext updateContext, ReadableMap options, Promise promise) {
181
210
  final String hash = options.getString("hash");
@@ -0,0 +1,10 @@
1
+ package expo.modules.pushy
2
+
3
+ import expo.modules.kotlin.modules.Module
4
+ import expo.modules.kotlin.modules.ModuleDefinition
5
+
6
+ class ExpoPushyModule : Module() {
7
+ override fun definition() = ModuleDefinition {
8
+ Name("ExpoPushy")
9
+ }
10
+ }
@@ -0,0 +1,27 @@
1
+ package expo.modules.pushy;
2
+
3
+ import android.content.Context;
4
+ import android.util.Log;
5
+ import androidx.annotation.Nullable;
6
+ import java.util.ArrayList;
7
+ import java.util.HashMap;
8
+ import java.util.List;
9
+ import java.util.Map;
10
+ import cn.reactnative.modules.update.UpdateContext;
11
+ import expo.modules.core.interfaces.Package;
12
+ import expo.modules.core.interfaces.ReactNativeHostHandler;
13
+
14
+ public class ExpoPushyPackage implements Package {
15
+ @Override
16
+ public List<ReactNativeHostHandler> createReactNativeHostHandlers(Context context) {
17
+ List<ReactNativeHostHandler> handlers = new ArrayList<>();
18
+ handlers.add(new ReactNativeHostHandler() {
19
+ @Nullable
20
+ @Override
21
+ public String getJSBundleFile(boolean useDeveloperSupport) {
22
+ return UpdateContext.getBundleUrl(context);
23
+ }
24
+ });
25
+ return handlers;
26
+ }
27
+ }
@@ -97,6 +97,11 @@ public class UpdateModule extends NativePushySpec {
97
97
  UpdateModuleImpl.reloadUpdate(updateContext, mContext, options,promise);
98
98
  }
99
99
 
100
+ @Override
101
+ public void restartApp(Promise promise) {
102
+ UpdateModuleImpl.restartApp(updateContext, mContext, promise);
103
+ }
104
+
100
105
  @Override
101
106
  public void setNeedUpdate(ReadableMap options,Promise promise) {
102
107
  UpdateModuleImpl.setNeedUpdate(updateContext, options,promise);
@@ -224,6 +224,29 @@ public class UpdateModule extends ReactContextBaseJavaModule {
224
224
  });
225
225
  }
226
226
 
227
+ @ReactMethod
228
+ public void restartApp(final Promise promise) {
229
+
230
+ UiThreadUtil.runOnUiThread(new Runnable() {
231
+ @Override
232
+ public void run() {
233
+ try {
234
+ final Context application = getReactApplicationContext().getApplicationContext();
235
+ ReactInstanceManager instanceManager = updateContext.getCustomReactInstanceManager();
236
+ if (instanceManager == null) {
237
+ instanceManager = ((ReactApplication) application).getReactNativeHost().getReactInstanceManager();
238
+ }
239
+ instanceManager.recreateReactContextInBackground();
240
+ promise.resolve(true);
241
+
242
+ } catch (Throwable err) {
243
+ promise.reject(err);
244
+ Log.e("pushy", "restartApp failed ", err);
245
+ }
246
+ }
247
+ });
248
+ }
249
+
227
250
  @ReactMethod
228
251
  public void setNeedUpdate(ReadableMap options) {
229
252
  final String hash = options.getString("hash");
@@ -0,0 +1,13 @@
1
+ {
2
+ "platforms": ["apple", "android"],
3
+ "apple": {
4
+ "modules": ["ExpoPushyModule"],
5
+ "reactDelegateHandlers": ["ExpoPushyReactDelegateHandler"],
6
+ "podspecPath":"react-native-update.podspec"
7
+ },
8
+ "android": {
9
+ "modules": [
10
+ "expo.modules.pushy.ExpoPushyModule"
11
+ ]
12
+ }
13
+ }
@@ -0,0 +1,7 @@
1
+ import ExpoModulesCore
2
+
3
+ public class ExpoPushyModule: Module {
4
+ public func definition() -> ModuleDefinition {
5
+ Name("ExpoPushy")
6
+ }
7
+ }
@@ -0,0 +1,10 @@
1
+ import ExpoModulesCore
2
+ import react_native_update
3
+
4
+ public final class ExpoPushyReactDelegateHandler: ExpoReactDelegateHandler {
5
+ private weak var reactDelegate: ExpoReactDelegate?
6
+
7
+ public override func bundleURL(reactDelegate: ExpoReactDelegate) -> URL? {
8
+ return RCTPushy.bundleURL()
9
+ }
10
+ }
@@ -338,6 +338,26 @@ RCT_EXPORT_METHOD(reloadUpdate:(NSDictionary *)options
338
338
  }
339
339
  }
340
340
 
341
+ RCT_EXPORT_METHOD(restartApp:(RCTPromiseResolveBlock)resolve
342
+ rejecter:(RCTPromiseRejectBlock)reject)
343
+ {
344
+ @try {
345
+ dispatch_async(dispatch_get_main_queue(), ^{
346
+ [self.bridge reload];
347
+ });
348
+ #if __has_include("RCTReloadCommand.h")
349
+ // reload 0.62+
350
+ RCTReloadCommandSetBundleURL([[self class] bundleURL]);
351
+ RCTTriggerReloadCommandListeners(@"pushy restartApp");
352
+ #endif
353
+
354
+ resolve(@true);
355
+ }
356
+ @catch (NSException *exception) {
357
+ reject(@"执行报错", exception.reason, nil);
358
+ }
359
+ }
360
+
341
361
  RCT_EXPORT_METHOD(markSuccess:(RCTPromiseResolveBlock)resolve
342
362
  rejecter:(RCTPromiseRejectBlock)reject)
343
363
  {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-update",
3
- "version": "10.27.1",
3
+ "version": "10.28.0",
4
4
  "description": "react-native hot update",
5
5
  "main": "src/index",
6
6
  "scripts": {
@@ -19,7 +19,7 @@ Pod::Spec.new do |s|
19
19
  s.platform = :ios, "8.0"
20
20
  s.platforms = { :ios => "11.0" }
21
21
  s.source = { :git => 'https://github.com/reactnativecn/react-native-update.git', :tag => '#{s.version}' }
22
- s.source_files = "ios/**/*.{h,m,mm,swift}"
22
+ s.source_files = Dir.glob("ios/**/*.{h,m,mm,swift}").reject { |f| f.start_with?("ios/Expo/") }
23
23
  s.libraries = 'bz2', 'z'
24
24
  s.vendored_libraries = 'RCTPushy/libRCTPushy.a'
25
25
  s.pod_target_xcconfig = {
@@ -33,11 +33,25 @@ Pod::Spec.new do |s|
33
33
  s.dependency "React-Core"
34
34
  s.dependency 'SSZipArchive'
35
35
 
36
+ project_root = File.expand_path('../../', __dir__)
37
+ project_package_json = File.join(project_root, 'package.json')
38
+ is_expo_project = false
39
+
40
+ if (File.exist?(project_package_json))
41
+ package_json = JSON.parse(File.read(project_package_json))
42
+ has_expo_dependency = package_json['dependencies'] && package_json['dependencies']['expo']
43
+ has_expo_modules_core = Dir.exist?('node_modules/expo-modules-core')
44
+ is_expo_project = has_expo_dependency || has_expo_modules_core
45
+ if is_expo_project
46
+ s.dependency 'ExpoModulesCore'
47
+ end
48
+ end
49
+
36
50
  s.subspec 'RCTPushy' do |ss|
37
51
  ss.source_files = 'ios/RCTPushy/*.{h,m,mm,swift}'
38
52
  ss.public_header_files = ['ios/RCTPushy/RCTPushy.h']
39
53
  end
40
-
54
+
41
55
  s.subspec 'HDiffPatch' do |ss|
42
56
  ss.source_files = ['ios/RCTPushy/HDiffPatch/**/*.{h,m,c}',
43
57
  'android/jni/hpatch.{h,c}',
@@ -47,7 +61,13 @@ Pod::Spec.new do |s|
47
61
  'android/jni/lzma/C/Lzma2Dec.{h,c}']
48
62
  ss.public_header_files = 'ios/RCTPushy/HDiffPatch/**/*.h'
49
63
  end
50
-
64
+
65
+ if is_expo_project
66
+ s.subspec 'Expo' do |ss|
67
+ ss.source_files = 'ios/Expo/**/*.{h,m,mm,swift}'
68
+ end
69
+ end
70
+
51
71
  if defined?(install_modules_dependencies()) != nil
52
72
  install_modules_dependencies(s);
53
73
  else
@@ -60,7 +80,6 @@ Pod::Spec.new do |s|
60
80
  "HEADER_SEARCH_PATHS" => "\"$(PODS_ROOT)/boost\"",
61
81
  "CLANG_CXX_LANGUAGE_STANDARD" => "c++17"
62
82
  }
63
-
64
83
  s.dependency "React-Codegen"
65
84
  s.dependency "RCT-Folly"
66
85
  s.dependency "RCTRequired"
@@ -15,6 +15,7 @@ export interface Spec extends TurboModule {
15
15
  getLocalHashInfo(hash: string): Promise<string>;
16
16
  setUuid(uuid: string): Promise<void>;
17
17
  reloadUpdate(options: { hash: string }): Promise<void>;
18
+ restartApp(): Promise<void>;
18
19
  setNeedUpdate(options: { hash: string }): Promise<void>;
19
20
  markSuccess(): Promise<void>;
20
21
  downloadPatchFromPpk(options: {
package/src/client.ts CHANGED
@@ -544,6 +544,9 @@ export class Pushy {
544
544
  delete Pushy.progressHandlers[progressKey];
545
545
  }
546
546
  };
547
+ restartApp = async () => {
548
+ return PushyModule.restartApp();
549
+ };
547
550
  }
548
551
 
549
552
  // for international users
package/src/context.ts CHANGED
@@ -13,6 +13,7 @@ export const defaultContext = {
13
13
  dismissError: noop,
14
14
  downloadUpdate: asyncNoop,
15
15
  downloadAndInstallApk: asyncNoop,
16
+ restartApp: asyncNoop,
16
17
  getCurrentVersionInfo: () => Promise.resolve({}),
17
18
  parseTestQrCode: () => false,
18
19
  currentHash: '',
@@ -33,6 +34,7 @@ export const UpdateContext = createContext<{
33
34
  metaInfo?: string;
34
35
  }>;
35
36
  parseTestQrCode: (code: string) => boolean;
37
+ restartApp: () => Promise<void>;
36
38
  currentHash: string;
37
39
  packageVersion: string;
38
40
  client?: Pushy | Cresc;
package/src/provider.tsx CHANGED
@@ -316,6 +316,10 @@ export const UpdateProvider = ({
316
316
  [parseTestPayload],
317
317
  );
318
318
 
319
+ const restartApp = useCallback(async () => {
320
+ return client.restartApp();
321
+ }, [client]);
322
+
319
323
  useEffect(() => {
320
324
  const parseLinking = (url: string | null) => {
321
325
  if (!url) {
@@ -361,6 +365,7 @@ export const UpdateProvider = ({
361
365
  downloadAndInstallApk,
362
366
  getCurrentVersionInfo,
363
367
  parseTestQrCode,
368
+ restartApp,
364
369
  }}>
365
370
  {children}
366
371
  </UpdateContext.Provider>
package/src/utils.ts CHANGED
@@ -77,10 +77,13 @@ export const testUrls = async (urls?: string[]) => {
77
77
  if (!urls?.length) {
78
78
  return null;
79
79
  }
80
- const ret = await promiseAny(urls.map(ping));
81
- if (ret) {
82
- return ret;
83
- }
80
+
81
+ try {
82
+ const ret = await promiseAny(urls.map(ping));
83
+ if (ret) {
84
+ return ret;
85
+ }
86
+ } catch {}
84
87
  log('all ping failed, use first url:', urls[0]);
85
88
  return urls[0];
86
89
  };