react-native-move-sdk 2.14.5 → 2.16.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.
Files changed (34) hide show
  1. package/android/build.gradle.kts +1 -1
  2. package/android/src/legacy/MoveSdkModule.kt +5 -0
  3. package/android/src/main/java/com/movesdk/NativeMoveSdkWrapper.kt +56 -3
  4. package/android/src/turbo/MoveSdkModule.kt +4 -0
  5. package/app.plugin.js +1 -0
  6. package/ios/MoveSdk.mm +26 -0
  7. package/ios/MoveSdk.swift +127 -48
  8. package/lib/commonjs/NativeMoveSdk.js.map +1 -1
  9. package/lib/commonjs/expo.js +138 -0
  10. package/lib/commonjs/expo.js.map +1 -0
  11. package/lib/commonjs/index.js +23 -4
  12. package/lib/commonjs/index.js.map +1 -1
  13. package/lib/module/NativeMoveSdk.js.map +1 -1
  14. package/lib/module/expo.js +133 -0
  15. package/lib/module/expo.js.map +1 -0
  16. package/lib/module/index.js +23 -4
  17. package/lib/module/index.js.map +1 -1
  18. package/lib/typescript/commonjs/src/NativeMoveSdk.d.ts +2 -1
  19. package/lib/typescript/commonjs/src/NativeMoveSdk.d.ts.map +1 -1
  20. package/lib/typescript/commonjs/src/expo.d.ts +7 -0
  21. package/lib/typescript/commonjs/src/expo.d.ts.map +1 -0
  22. package/lib/typescript/commonjs/src/index.d.ts +2 -0
  23. package/lib/typescript/commonjs/src/index.d.ts.map +1 -1
  24. package/lib/typescript/module/src/NativeMoveSdk.d.ts +2 -1
  25. package/lib/typescript/module/src/NativeMoveSdk.d.ts.map +1 -1
  26. package/lib/typescript/module/src/expo.d.ts +7 -0
  27. package/lib/typescript/module/src/expo.d.ts.map +1 -0
  28. package/lib/typescript/module/src/index.d.ts +2 -0
  29. package/lib/typescript/module/src/index.d.ts.map +1 -1
  30. package/package.json +5 -2
  31. package/react-native-move-sdk.podspec +5 -1
  32. package/src/NativeMoveSdk.ts +5 -1
  33. package/src/expo.tsx +203 -0
  34. package/src/index.tsx +31 -18
@@ -16,7 +16,11 @@ Pod::Spec.new do |s|
16
16
 
17
17
  s.source_files = "ios/**/*.{h,m,mm,cpp,swift}"
18
18
 
19
- s.dependency 'DolphinMoveSDK', '2.14.3.320'
19
+ s.dependency 'DolphinMoveSDK', '2.16.0.335'
20
+
21
+ if ENV['DOLPHIN_MOVE_SDK_HEALTH'] == '1' then
22
+ s.dependency 'DolphinMoveSDKHealth', '2.16.0.335'
23
+ end
20
24
 
21
25
  # Use install_modules_dependencies helper to install the dependencies if React Native version >=0.71.0.
22
26
  # See https://github.com/facebook/react-native/blob/febf6b7f33fdb4904669f99d795eba4c0f95d7bf/scripts/cocoapods/new_architecture.rb#L79.
@@ -52,7 +52,9 @@ export type WarningReasons =
52
52
  | 'LOCATION_POWER_MODE(3)'
53
53
  | 'LOCATION_POWER_MODE(4)'
54
54
  | 'ENERGY_SAVER'
55
- | 'BACKGROUND_READ_STEPS_MISSING_IN_SYSTEM';
55
+ | 'BACKGROUND_READ_STEPS_MISSING_IN_SYSTEM'
56
+ | 'HEALTH_DEPENDENCY_MISSING'
57
+ | 'HEALTHKIT_NO_STEPS_DETECTED';
56
58
  export type IssueListService = TimelineDetectionService | DrivingService | WalkingService;
57
59
  export type ErrorListType = Array<IssueListItem<ErrorReasons>>;
58
60
  export type WarningListType = Array<IssueListItem<WarningReasons>>;
@@ -154,6 +156,8 @@ export interface Spec extends TurboModule {
154
156
 
155
157
  geocode(latitude: number, longitude: number): Promise<string>;
156
158
 
159
+ getMoveConfig(): Promise<MoveSdkConfig>;
160
+
157
161
  getRegisteredDevices(): Promise<Array<MoveSdkDevice>>;
158
162
 
159
163
  getState(): Promise<SdkState>;
package/src/expo.tsx ADDED
@@ -0,0 +1,203 @@
1
+ import {
2
+ createRunOncePlugin,
3
+ type ConfigPlugin,
4
+ withDangerousMod,
5
+ withAndroidManifest,
6
+ AndroidConfig,
7
+ withMainActivity,
8
+ withProjectBuildGradle,
9
+ withMainApplication,
10
+ } from '@expo/config-plugins';
11
+ import { mergeContents } from '@expo/config-plugins/build/utils/generateCode';
12
+ import type { ExpoConfig } from '@expo/config-types';
13
+ import * as fs from 'fs/promises';
14
+ import * as path from 'path';
15
+
16
+ type Props = {
17
+ extensions?: ('Development' | 'Health')[];
18
+ };
19
+
20
+ function withMoveAndroidMainApplication(config: ExpoConfig) {
21
+ return withMainApplication(config, (cfg) => {
22
+ const { modResults } = cfg;
23
+ const { contents } = modResults;
24
+ const lines = contents.split('\n');
25
+
26
+ const importIndex = lines.findIndex((line: string) =>
27
+ /^package/.test(line)
28
+ );
29
+ if (importIndex !== -1) {
30
+ // Replace 'in' with '`in`' in the package name
31
+ lines[importIndex] = lines[importIndex]!.replace(
32
+ 'package in',
33
+ 'package `in`'
34
+ );
35
+ }
36
+ const mainApplicationIndex = lines.findIndex((line: string) =>
37
+ /^class MainApplication : Application\(\), ReactApplication {$/.test(line)
38
+ );
39
+
40
+ const onCreateIndex = lines.findIndex((line: string) =>
41
+ /super.onCreate\(\)/.test(line)
42
+ );
43
+
44
+ modResults.contents = [
45
+ ...lines.slice(0, importIndex + 1),
46
+ `import com.movesdk.NativeMoveSdkWrapper`,
47
+ ...lines.slice(importIndex + 1, mainApplicationIndex + 1),
48
+ ` private lateinit var sdkWrapper: NativeMoveSdkWrapper`,
49
+ ...lines.slice(mainApplicationIndex + 1, onCreateIndex + 1),
50
+ ` sdkWrapper = NativeMoveSdkWrapper.getInstance(this)`,
51
+ ` sdkWrapper.init(this)`,
52
+ ...lines.slice(onCreateIndex + 1),
53
+ ].join('\n');
54
+
55
+ return cfg;
56
+ });
57
+ }
58
+
59
+ function withMoveAndroidProjectBuildGradle(config: ExpoConfig) {
60
+ return withProjectBuildGradle(config, (cfg) => {
61
+ const { modResults } = cfg;
62
+ const { contents } = modResults;
63
+ const lines = contents.split('\n');
64
+
65
+ const mavenIndex = lines.lastIndexOf('allprojects {') + 1;
66
+
67
+ modResults.contents = [
68
+ ...lines.slice(0, mavenIndex + 1),
69
+ ` maven {`,
70
+ ` url "https://dolphin.jfrog.io/artifactory/move-sdk-libs-release"`,
71
+ ` content {`,
72
+ ` includeGroup "io.dolphin.move"`,
73
+ ` }`,
74
+ ` }`,
75
+ ...lines.slice(mavenIndex + 1),
76
+ ].join('\n');
77
+
78
+ return cfg;
79
+ });
80
+ }
81
+
82
+ function withMoveAndroidHealth(config: ExpoConfig) {
83
+ config = withMainActivity(config, async (cfg) => {
84
+ const mainActivity = cfg.modResults;
85
+
86
+ const importStatement = 'import com.movesdk.NativeMoveSdkWrapper';
87
+ if (!mainActivity.contents.includes(importStatement)) {
88
+ mainActivity.contents = mainActivity.contents.replace(
89
+ /import android.os.Bundle/,
90
+ `import android.os.Bundle\n${importStatement}`
91
+ );
92
+ }
93
+
94
+ const codeToAdd =
95
+ 'NativeMoveSdkWrapper.getInstance(this.applicationContext).registerRequestPermissionLauncher(this)';
96
+ if (!mainActivity.contents.includes(codeToAdd)) {
97
+ mainActivity.contents = mainActivity.contents.replace(
98
+ /super\.onCreate\(null\)/,
99
+ `${codeToAdd}\n super.onCreate(null)`
100
+ );
101
+ }
102
+
103
+ return cfg;
104
+ });
105
+
106
+ config = withAndroidManifest(config, async (cfg) => {
107
+ const mainApplication = AndroidConfig.Manifest.getMainApplicationOrThrow(
108
+ cfg.modResults
109
+ );
110
+
111
+ const mainActivity = mainApplication.activity?.find(
112
+ (activity) => activity.$['android:name'] === '.MainActivity'
113
+ );
114
+
115
+ if (mainActivity) {
116
+ if (!mainActivity['intent-filter']) {
117
+ mainActivity['intent-filter'] = [];
118
+ }
119
+
120
+ // Add Health Connect permission rationale intent filter
121
+ mainActivity['intent-filter'].push({
122
+ action: [
123
+ {
124
+ $: {
125
+ 'android:name':
126
+ 'androidx.health.ACTION_SHOW_PERMISSIONS_RATIONALE',
127
+ },
128
+ },
129
+ ],
130
+ category: [
131
+ {
132
+ $: { 'android:name': 'android.intent.category.HEALTH_PERMISSIONS' },
133
+ },
134
+ ],
135
+ });
136
+
137
+ // Add View Permission Usage intent filter
138
+ mainActivity['intent-filter'].push({
139
+ action: [
140
+ {
141
+ $: {
142
+ 'android:name': 'android.intent.action.VIEW_PERMISSION_USAGE',
143
+ },
144
+ },
145
+ ],
146
+ category: [
147
+ {
148
+ $: { 'android:name': 'android.intent.category.HEALTH_PERMISSIONS' },
149
+ },
150
+ ],
151
+ });
152
+ }
153
+
154
+ return cfg;
155
+ });
156
+
157
+ config = withAndroidManifest(config, async (cfg) => {
158
+ const permissions = [
159
+ 'android.permission.health.READ_HEALTH_DATA_IN_BACKGROUND',
160
+ 'android.permission.health.READ_STEPS',
161
+ ];
162
+ cfg.modResults.manifest['uses-permission'] = [
163
+ ...(cfg.modResults.manifest['uses-permission'] || []),
164
+ ...permissions.map((perm) => ({ $: { 'android:name': perm } })),
165
+ ];
166
+ return cfg;
167
+ });
168
+
169
+ return config;
170
+ }
171
+
172
+ const withExtensions: ConfigPlugin<Props> = (config, { extensions = [] }) =>
173
+ withDangerousMod(config, [
174
+ 'ios',
175
+ async (config) => {
176
+ const file = path.join(config.modRequest.platformProjectRoot, 'Podfile');
177
+ const contents = await fs.readFile(file, 'utf8');
178
+
179
+ const withSetup = mergeContents({
180
+ tag: 'setup-move-sdk',
181
+ src: contents,
182
+ anchor: /^prepare_react_native_project!$/m,
183
+ newSrc: `ENV['DOLPHIN_MOVE_SDK_HEALTH'] = '${extensions.includes('Health') ? '1' : '0'}'`,
184
+ offset: 1,
185
+ comment: '#',
186
+ });
187
+
188
+ await fs.writeFile(file, withSetup.contents, 'utf-8');
189
+ return config;
190
+ },
191
+ ]);
192
+
193
+ const withMove: ConfigPlugin<Props> = (config, { extensions = [] }) => {
194
+ config = withExtensions(config, { extensions });
195
+ if (extensions.includes('Health')) {
196
+ config = withMoveAndroidHealth(config);
197
+ }
198
+ config = withMoveAndroidMainApplication(config);
199
+ config = withMoveAndroidProjectBuildGradle(config);
200
+ return config;
201
+ };
202
+
203
+ export default createRunOncePlugin(withMove, 'react-native-move-sdk');
package/src/index.tsx CHANGED
@@ -81,13 +81,13 @@ const eventEmitter = new NativeEventEmitter(MoveSdkModule);
81
81
  const NativeMoveSdk = MoveSdkModule
82
82
  ? MoveSdkModule
83
83
  : new Proxy(
84
- {},
85
- {
86
- get() {
87
- throw new Error(LINKING_ERROR);
88
- },
89
- }
90
- );
84
+ {},
85
+ {
86
+ get() {
87
+ throw new Error(LINKING_ERROR);
88
+ },
89
+ }
90
+ );
91
91
 
92
92
  export default class MoveSdk {
93
93
  static READY: SdkState = 'READY';
@@ -153,13 +153,13 @@ export default class MoveSdk {
153
153
  auth,
154
154
  // Config
155
155
  config,
156
- options,
156
+ options ?? {},
157
157
  // Platform config
158
158
  platformParams
159
159
  );
160
160
  }
161
161
 
162
- static async setupWithCode(code:string, config: MoveSdkConfig, android: MoveSdkAndroidConfig, options?: MoveSdkOptions): Promise<void> {
162
+ static async setupWithCode(code: string, config: MoveSdkConfig, android: MoveSdkAndroidConfig, options?: MoveSdkOptions): Promise<void> {
163
163
 
164
164
  let platformParams: Array<string | boolean> = [];
165
165
  if (Platform.OS === 'android') {
@@ -183,14 +183,18 @@ export default class MoveSdk {
183
183
  code,
184
184
  // Config
185
185
  config,
186
- options,
186
+ options ?? {},
187
187
  // Platform config
188
188
  platformParams
189
189
  );
190
190
  }
191
191
 
192
192
  static allowMockLocations(allowMockLocations: boolean) {
193
- NativeMoveSdk.allowMockLocations(allowMockLocations);
193
+ if (isTurboModuleEnabled) {
194
+ NativeMoveSdk.allowMockLocations(allowMockLocations);
195
+ } else {
196
+ NativeMoveSdk.mockLocations(allowMockLocations);
197
+ }
194
198
  }
195
199
 
196
200
  static resolveError() {
@@ -309,7 +313,7 @@ export default class MoveSdk {
309
313
 
310
314
  static addLogListener(logReceived: (event: MoveSdkLog) => void): EmitterSubscription {
311
315
  return eventEmitter.addListener('MOVE_SDK_LOG', (event) => {
312
- logReceived(event);
316
+ logReceived(event);
313
317
  });
314
318
  }
315
319
 
@@ -320,8 +324,8 @@ export default class MoveSdk {
320
324
  }
321
325
 
322
326
  static addHealthListener(scoreReceived: (health: Array<HealthListItem>) => void): EmitterSubscription {
323
- return eventEmitter.addListener('MOVE_SDK_HEALTH', (health) => {
324
- scoreReceived(health);
327
+ return eventEmitter.addListener('MOVE_SDK_HEALTH', (health) => {
328
+ scoreReceived(health);
325
329
  });
326
330
  }
327
331
 
@@ -353,6 +357,10 @@ export default class MoveSdk {
353
357
  return NativeMoveSdk.getDeviceQualifier();
354
358
  }
355
359
 
360
+ static async getMoveConfig(): Promise<MoveSdkConfig> {
361
+ return await NativeMoveSdk.getMoveConfig();
362
+ }
363
+
356
364
  static async geocode(latitude: number, longitude: number): Promise<string> {
357
365
  return await NativeMoveSdk.geocode(latitude, longitude);
358
366
  }
@@ -420,11 +428,11 @@ export default class MoveSdk {
420
428
  }
421
429
 
422
430
  static async getBluetoothPermission() {
423
- return await NativeMoveSdk.getBluetoothPermission();
431
+ return await NativeMoveSdk.getBluetoothPermission();
424
432
  }
425
433
 
426
434
  static async getBluetoothState() {
427
- return await NativeMoveSdk.getBluetoothState();
435
+ return await NativeMoveSdk.getBluetoothState();
428
436
  }
429
437
 
430
438
  static addDeviceDiscoveryListener(onScanResult: (state: Array<MoveScanResult>) => void): EmitterSubscription {
@@ -463,10 +471,10 @@ export default class MoveSdk {
463
471
  }
464
472
 
465
473
  static updateConfig(config: MoveSdkConfig, options?: MoveSdkOptions) {
466
- NativeMoveSdk.updateConfig(config, options);
474
+ NativeMoveSdk.updateConfig(config, options ?? {});
467
475
  }
468
476
 
469
- static setTripMetadata(metadata?: {[key: string]: string}) {
477
+ static setTripMetadata(metadata?: { [key: string]: string }) {
470
478
  NativeMoveSdk.setTripMetadata(metadata);
471
479
  }
472
480
 
@@ -481,4 +489,9 @@ export default class MoveSdk {
481
489
  static async requestHealthPermissions(): Promise<HealthPermissionsResult> {
482
490
  return await NativeMoveSdk.requestHealthPermissions();
483
491
  }
492
+
493
+ static beaconDevices(serviceUUID: string): MoveSdkDevice {
494
+ const name = `Beacons ${serviceUUID}`
495
+ return { id: serviceUUID, name: name, data: JSON.stringify({ id: serviceUUID, name: name, uuid: serviceUUID }) };
496
+ }
484
497
  }