react-native-beidou 1.1.4 → 1.1.7

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 (55) hide show
  1. package/Compass.android.tsx +4 -12
  2. package/Compass.ios.tsx +2 -3
  3. package/android/build.gradle +15 -2
  4. package/android/src/main/AndroidManifest.xml +1 -0
  5. package/android/src/main/java/com/fxzs.rnbeidou/BeiDouBluetoothModule.java +425 -185
  6. package/android/src/main/java/com/fxzs.rnbeidou/BeiDouBluetoothPackage.java +10 -13
  7. package/android/src/main/java/com/fxzs.rnbeidou/BeidouAidlHelper.java +45 -13
  8. package/android/src/main/java/com/fxzs.rnbeidou/SuperSimModule.java +301 -0
  9. package/android/src/main/java/com/fxzs.rnbeidou/view/CompassManager.java +15 -15
  10. package/android/src/main/java/com/fxzs.rnbeidou/view/CompassView.java +10 -4
  11. package/index.ts +100 -35
  12. package/ios/BeiDouBluetoothModule.m +147 -20
  13. package/ios/BeidouBluetooth.framework/BeidouBluetooth +0 -0
  14. package/ios/BeidouBluetooth.framework/FMDB.bundle/Info.plist +0 -0
  15. package/ios/BeidouBluetooth.framework/FMDB.bundle/PrivacyInfo.xcprivacy +14 -0
  16. package/ios/BeidouBluetooth.framework/Info.plist +0 -0
  17. package/ios/BeidouBluetooth.framework/_CodeSignature/CodeDirectory +0 -0
  18. package/ios/BeidouBluetooth.framework/_CodeSignature/CodeRequirements +0 -0
  19. package/ios/BeidouBluetooth.framework/_CodeSignature/CodeResources +11 -39
  20. package/ios/BeidouBluetooth.framework/_CodeSignature/CodeSignature +0 -0
  21. package/ios/CompassView.h +1 -0
  22. package/ios/CompassView.m +3 -0
  23. package/ios/CompassViewComponentView.h +11 -0
  24. package/ios/CompassViewComponentView.mm +64 -0
  25. package/package.json +3 -5
  26. package/react-native-beidou.podspec +2 -2
  27. package/src/CompassViewNativeComponent.ts +13 -0
  28. package/src/NativeBeiDouBluetooth.ts +57 -0
  29. package/src/NativeSuperSim.ts +21 -0
  30. package/BeiDouAIDLTestPage.tsx +0 -710
  31. package/LogManager.ts +0 -284
  32. package/TestPage.ts +0 -6
  33. package/android/.gradle/8.10/checksums/checksums.lock +0 -0
  34. package/android/.gradle/8.10/dependencies-accessors/gc.properties +0 -0
  35. package/android/.gradle/8.10/fileChanges/last-build.bin +0 -0
  36. package/android/.gradle/8.10/fileHashes/fileHashes.lock +0 -0
  37. package/android/.gradle/8.10/gc.properties +0 -0
  38. package/android/.gradle/8.9/checksums/checksums.lock +0 -0
  39. package/android/.gradle/8.9/dependencies-accessors/gc.properties +0 -0
  40. package/android/.gradle/8.9/fileChanges/last-build.bin +0 -0
  41. package/android/.gradle/8.9/fileHashes/fileHashes.lock +0 -0
  42. package/android/.gradle/8.9/gc.properties +0 -0
  43. package/android/.gradle/buildOutputCleanup/buildOutputCleanup.lock +0 -0
  44. package/android/.gradle/buildOutputCleanup/cache.properties +0 -2
  45. package/android/.gradle/config.properties +0 -2
  46. package/android/.gradle/vcs-1/gc.properties +0 -0
  47. package/android/.idea/AndroidProjectSystem.xml +0 -6
  48. package/android/.idea/caches/deviceStreaming.xml +0 -1306
  49. package/android/.idea/gradle.xml +0 -13
  50. package/android/.idea/migrations.xml +0 -10
  51. package/android/.idea/misc.xml +0 -9
  52. package/android/.idea/runConfigurations.xml +0 -17
  53. package/android/.idea/vcs.xml +0 -6
  54. package/android/local.properties +0 -8
  55. package/android/src/main/java/com/fxzs.rnbeidou/LogManager.java +0 -488
package/index.ts CHANGED
@@ -1,21 +1,7 @@
1
- import { NativeModules, Platform } from 'react-native';
2
-
3
- const LINKING_ERROR =
4
- `The package 'react-native-beidou' doesn't seem to be linked. Make sure: \n\n` +
5
- Platform.select({ ios: "- You have run 'pod install'\n", default: '' }) +
6
- '- You rebuilt the app after installing the package\n' +
7
- '- You are not using Expo Go\n';
8
-
9
- const BeiDouBluetoothModule = NativeModules.BeiDouBluetoothModule
10
- ? NativeModules.BeiDouBluetoothModule
11
- : new Proxy(
12
- {},
13
- {
14
- get() {
15
- throw new Error(LINKING_ERROR);
16
- },
17
- }
18
- );
1
+ import NativeBeiDouBluetooth from './src/NativeBeiDouBluetooth';
2
+ import NativeSuperSim from './src/NativeSuperSim';
3
+
4
+ const BeiDouBluetoothModule = NativeBeiDouBluetooth;
19
5
 
20
6
  // ================== 蓝牙相关类型定义 ==================
21
7
  export interface BlueDeviceInfo {
@@ -89,6 +75,19 @@ export interface SimCardInfo {
89
75
  number: string | null;
90
76
  }
91
77
 
78
+ export interface ContactInfo {
79
+ id: string;
80
+ name: string;
81
+ firstLetter: string;
82
+ phoneNumbers: string[];
83
+ }
84
+
85
+ export interface SuperSimBaseResponse {
86
+ code?: number;
87
+ statusMsg?: string;
88
+ [key: string]: unknown;
89
+ }
90
+
92
91
  // ================== 导出的便利方法 ==================
93
92
 
94
93
  /**
@@ -160,6 +159,14 @@ export const getSimCardList = async (): Promise<SimCardInfo[]> => {
160
159
  return list ?? [];
161
160
  };
162
161
 
162
+ /**
163
+ * 获取通讯录联系人(仅包含有号码的联系人)
164
+ */
165
+ export const getContactsList = async (): Promise<ContactInfo[]> => {
166
+ const list = await BeiDouBluetoothModule.getContacts();
167
+ return (list ?? []) as ContactInfo[];
168
+ };
169
+
163
170
  /**
164
171
  * 绑定北斗AIDL服务
165
172
  * @param packageName 北斗服务的包名
@@ -202,10 +209,11 @@ export const checkBeiDouKey = async (slotId: number): Promise<number> => {
202
209
  */
203
210
  export const encryptCommonBeiDouMessage = async (
204
211
  slotId: number,
212
+ speedType: string,
205
213
  receiveList: string[],
206
214
  inputMsg: string
207
215
  ): Promise<BDMsgEncryptResponse> => {
208
- return await BeiDouBluetoothModule.commonBDMsgEncrypt(slotId, receiveList, inputMsg);
216
+ return await BeiDouBluetoothModule.commonBDMsgEncrypt(slotId,speedType, receiveList, inputMsg);
209
217
  };
210
218
 
211
219
  /**
@@ -213,12 +221,13 @@ export const encryptCommonBeiDouMessage = async (
213
221
  */
214
222
  export const encryptPositionBeiDouMessage = async (
215
223
  slotId: number,
224
+ speedType: string,
216
225
  receiveList: string[],
217
226
  inputMsg: string,
218
227
  longitude: number,
219
228
  latitude: number
220
229
  ): Promise<BDMsgEncryptResponse> => {
221
- return await BeiDouBluetoothModule.positionBDMsgEncrypt(slotId, receiveList, inputMsg, longitude, latitude);
230
+ return await BeiDouBluetoothModule.positionBDMsgEncrypt(slotId, speedType,receiveList, inputMsg, longitude, latitude);
222
231
  };
223
232
 
224
233
  /**
@@ -325,6 +334,75 @@ export const setBeiDouBLEKey = async (bleKey: string): Promise<boolean> => {
325
334
  }
326
335
  };
327
336
 
337
+ const getSuperSimModule = () => {
338
+ if (!NativeSuperSim) {
339
+ throw new Error('SuperSimModule is not available. Ensure Android native module is linked correctly.');
340
+ }
341
+ return NativeSuperSim;
342
+ };
343
+
344
+ export const getSuperSimType = async (slotId: number): Promise<number> => {
345
+ return getSuperSimModule().getSimType(slotId);
346
+ };
347
+
348
+ export const getSuperSimKsKeyAndAuthResult = async (slotId: number): Promise<SuperSimBaseResponse | null> => {
349
+ return (await getSuperSimModule().getKsKeyAndAuthResult(slotId)) as SuperSimBaseResponse | null;
350
+ };
351
+
352
+ export const checkSuperSimKeyIsExistAndValidate = async (slotId: number): Promise<number> => {
353
+ return getSuperSimModule().checkKeyIsExistAndValidate(slotId);
354
+ };
355
+
356
+ export const encryptSuperSimCommonMessage = async (
357
+ slotId: number,
358
+ recipients: string[] | null,
359
+ message: string
360
+ ): Promise<SuperSimBaseResponse | null> => {
361
+ return (await getSuperSimModule().commonMessageEncryptBDMsg(slotId, recipients, message)) as SuperSimBaseResponse | null;
362
+ };
363
+
364
+ export const encryptSuperSimPositionReport = async (
365
+ slotId: number,
366
+ recipients: string[] | null,
367
+ message: string,
368
+ longitude: number,
369
+ latitude: number
370
+ ): Promise<SuperSimBaseResponse | null> => {
371
+ return (await getSuperSimModule().positionReportEncryptBDMsg(slotId, recipients, message, longitude, latitude)) as SuperSimBaseResponse | null;
372
+ };
373
+
374
+ export const encryptSuperSimMailboxQuery = async (slotId: number): Promise<SuperSimBaseResponse | null> => {
375
+ return (await getSuperSimModule().mailboxQueryEncryptBDMsg(slotId)) as SuperSimBaseResponse | null;
376
+ };
377
+
378
+ export const decryptSuperSimMailboxReply = async (
379
+ slotId: number,
380
+ data: number[] | null,
381
+ dataLength: number
382
+ ): Promise<SuperSimBaseResponse | null> => {
383
+ return (await getSuperSimModule().mailboxReplyDecryptBDMsg(slotId, data, dataLength)) as SuperSimBaseResponse | null;
384
+ };
385
+
386
+ export const getSuperSimCurrentUserInfo = async (slotId: number): Promise<SuperSimBaseResponse | null> => {
387
+ return (await getSuperSimModule().getCurrentUserInfo(slotId)) as SuperSimBaseResponse | null;
388
+ };
389
+
390
+ export const decryptSuperSimMailboxSynchronize = async (slotId: number): Promise<SuperSimBaseResponse | null> => {
391
+ return (await getSuperSimModule().mailboxSynchronizeDecryptBDMsg(slotId)) as SuperSimBaseResponse | null;
392
+ };
393
+
394
+ export const SuperSim = {
395
+ getSimType: getSuperSimType,
396
+ getKsKeyAndAuthResult: getSuperSimKsKeyAndAuthResult,
397
+ checkKeyIsExistAndValidate: checkSuperSimKeyIsExistAndValidate,
398
+ encryptCommonMessage: encryptSuperSimCommonMessage,
399
+ encryptPositionReport: encryptSuperSimPositionReport,
400
+ encryptMailboxQuery: encryptSuperSimMailboxQuery,
401
+ decryptMailboxReply: decryptSuperSimMailboxReply,
402
+ getCurrentUserInfo: getSuperSimCurrentUserInfo,
403
+ decryptMailboxSynchronize: decryptSuperSimMailboxSynchronize,
404
+ };
405
+
328
406
  export const BeiDouModule = {
329
407
  // 蓝牙相关
330
408
  bluetooth: {
@@ -355,6 +433,7 @@ export const BeiDouModule = {
355
433
  initializeBluetooth,
356
434
  fetchCurrentWifiName,
357
435
  getSimCardList,
436
+ getContacts: getContactsList,
358
437
  getGpsLocation: (): Promise<{
359
438
  latitude: number;
360
439
  longitude: number;
@@ -405,6 +484,7 @@ export const BeiDouModule = {
405
484
  getMessagesForPhone: getMessagesForPhoneNumber,
406
485
  setBLEKey: BeiDouBluetoothModule.setBLEKey,
407
486
  getSimCardList: BeiDouBluetoothModule.getSimCardList,
487
+ getContacts: BeiDouBluetoothModule.getContacts,
408
488
 
409
489
  // 北斗AIDL服务绑定方法
410
490
  bindBeidouServiceMethod: BeiDouBluetoothModule.bindBeidouServiceMethod,
@@ -432,18 +512,3 @@ export const BeiDouModule = {
432
512
  export default BeiDouModule;
433
513
  export { default as Compass } from './Compass';
434
514
 
435
- // 导出日志管理功能
436
- export {
437
- BeiDouLogManager,
438
- BeiDouLogger,
439
- LogLevel,
440
- logVerbose,
441
- logDebug,
442
- logInfo,
443
- logWarn,
444
- logError,
445
- setupGlobalLogInterception
446
- } from './LogManager';
447
- export type { LogConfig } from './LogManager';
448
-
449
-
@@ -9,6 +9,7 @@
9
9
  #import <BeidouBluetooth/BeidouBluetooth.h>
10
10
  #import <React/RCTRootView.h>
11
11
  #import "BDTChatDBManager.h"
12
+ #import <Contacts/Contacts.h>
12
13
 
13
14
  @interface BeiDouBluetoothModule () <BDTBluetoothMonitor>
14
15
 
@@ -29,30 +30,33 @@ RCT_EXPORT_MODULE();
29
30
 
30
31
  - (instancetype)init {
31
32
  self = [super init];
32
- if (self) {
33
-
34
- [BDTBluetoothManager shared].delegate = self;
35
-
36
- }
37
33
  return self;
38
34
  }
39
35
 
36
+ - (BDTBluetoothManager *)bluetoothManager {
37
+ BDTBluetoothManager *manager = [BDTBluetoothManager shared];
38
+ if (manager.delegate != self) {
39
+ manager.delegate = self;
40
+ }
41
+ return manager;
42
+ }
43
+
40
44
  -(NSArray<NSString *> *)supportedEvents{
41
- return @[@"suncthing_success",@"nasConnectFailed",@"exitTCN100",@"screenshotNotice",@"noticeUploadSpeed",@"etsNoticeUploadComplete",@"listenUpdateNotice",@"listenBluetoolth",@"listenNetStatus"];
45
+ return @[@"listenBluetoolth",@"beidouBluetoothError"];
42
46
  }
43
47
 
44
48
 
45
49
  /// 开始扫描
46
50
  /// - Parameter param: 当系统或者应用蓝牙开关关闭时会触发此回调 3:用户拒绝授权 4:系统蓝牙开关关闭
47
51
  RCT_EXPORT_METHOD(startScanForService:(RCTResponseSenderBlock)callBack) {
48
- [[BDTBluetoothManager shared] startScanningForServices:nil callBack:^(NSInteger statu) {
52
+ [[self bluetoothManager] startScanningForServices:nil callBack:^(NSInteger statu) {
49
53
  callBack(@[@(statu)]);
50
54
  }];
51
55
  }
52
56
 
53
57
  /// 结束扫描
54
58
  RCT_EXPORT_METHOD(stopScanning) {
55
- [[BDTBluetoothManager shared] stopScanning];
59
+ [[self bluetoothManager] stopScanning];
56
60
  }
57
61
 
58
62
  /// 获取扫描到的蓝牙设备列表
@@ -61,7 +65,7 @@ RCT_EXPORT_METHOD(stopScanning) {
61
65
  RCT_EXPORT_METHOD(getDiscoveredDevices:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) {
62
66
 
63
67
  @try {
64
- NSArray<BDTBluetoothDevice *> * deviceArr = [[BDTBluetoothManager shared] getDiscoveredDevices];
68
+ NSArray<BDTBluetoothDevice *> * deviceArr = [[self bluetoothManager] getDiscoveredDevices];
65
69
  NSMutableArray *deviceArray = [NSMutableArray array];
66
70
  for (BDTBluetoothDevice *device in deviceArr) {
67
71
  NSMutableDictionary *infoDic = [NSMutableDictionary dictionary];
@@ -98,7 +102,7 @@ RCT_EXPORT_METHOD(connectToDeviceFromCloudDeviceNO:(NSString *)deviceNO
98
102
  timeout:(nonnull NSNumber *)second
99
103
  resolve:(RCTPromiseResolveBlock)resolve
100
104
  rejecter:(RCTPromiseRejectBlock)reject) {
101
- [[BDTBluetoothManager shared] connectPeripheralDeviceNO:deviceNO timeout:[second intValue] callback:^(NSInteger state) {
105
+ [[self bluetoothManager] connectPeripheralDeviceNO:deviceNO timeout:[second intValue] callback:^(NSInteger state) {
102
106
  if (state == 1) {
103
107
  resolve(@"1");
104
108
  } else {
@@ -113,7 +117,7 @@ RCT_EXPORT_METHOD(connectToDeviceFromCloudDeviceNO:(NSString *)deviceNO
113
117
  /// - Parameter resolve: 连接成功回调
114
118
  /// - Parameter reject: 连接失败回调
115
119
  RCT_EXPORT_METHOD(disConnectWithDeviceUUID:(NSString *)identifier resolve:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) {
116
- [[BDTBluetoothManager shared] disconnect:identifier callback:^(NSInteger result) {
120
+ [[self bluetoothManager] disconnect:identifier callback:^(NSInteger result) {
117
121
  if (result == 1) {
118
122
  NSLog(@"断开连接成功");
119
123
  resolve(@"1");
@@ -148,7 +152,7 @@ RCT_EXPORT_METHOD(writeData:(NSString *)base64String
148
152
  }
149
153
  uint8_t commandValue = [command shortValue];
150
154
  BOOL isEncrypted = [encrypted boolValue];
151
- [[BDTBluetoothManager shared] sendBusinessData:decodedData
155
+ [[self bluetoothManager] sendBusinessData:decodedData
152
156
  deviceId:deviceNO
153
157
  command:commandValue
154
158
  opcode:0
@@ -198,7 +202,7 @@ RCT_EXPORT_METHOD(writeInfo:(nullable NSString *)base64Payload
198
202
  uint8_t opCodeValue = [opCode shortValue];
199
203
  uint16_t attrTypeValue = [attrType shortValue];
200
204
  BOOL isEncrypted = [encrypted boolValue];
201
- [[BDTBluetoothManager shared] sendBusinessData:decodedData
205
+ [[self bluetoothManager] sendBusinessData:decodedData
202
206
  deviceId:deviceNO
203
207
  command:commandValue
204
208
  opcode:opCodeValue
@@ -253,7 +257,7 @@ RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(generateRandom16BytesString) {
253
257
  /// 获取蓝牙状态
254
258
  /// - Parameter callback: 0:未决定蓝牙权限 1:蓝牙权限受限 2:拒绝蓝牙权限 3:已授权蓝牙权限
255
259
  RCT_EXPORT_METHOD(getBluetoothState:(RCTResponseSenderBlock)callback) {
256
- NSInteger state = [[BDTBluetoothManager shared] getBluetoothState];
260
+ NSInteger state = [[self bluetoothManager] getBluetoothState];
257
261
  NSNumber *stateNum = [NSNumber numberWithInteger:state];
258
262
  callback(@[stateNum]);
259
263
  }
@@ -280,9 +284,14 @@ RCT_EXPORT_METHOD(getBluetoothState:(RCTResponseSenderBlock)callback) {
280
284
 
281
285
 
282
286
  RCT_EXPORT_METHOD(fetchCurrentWifiName:(RCTResponseSenderBlock)callback) {
283
- NSString *name = [[BDTBluetoothManager shared] fetchCurrentWiFiSSID];
284
- NSLog(@"wifi名称:%@",name);
285
- callback(@[name]);
287
+ NSString *name = [[self bluetoothManager] fetchCurrentWiFiSSID];
288
+ if (name == nil || name.length == 0 || [name isEqualToString:@"(null)"]) {
289
+ name = @"未连接";
290
+ }
291
+ NSLog(@"wifi名称:%@", name);
292
+ if (callback) {
293
+ callback(@[name]);
294
+ }
286
295
  }
287
296
 
288
297
 
@@ -357,7 +366,7 @@ RCT_EXPORT_METHOD(startMiniAppForBluetoolthDevice:(NSString *)bundleFilePath
357
366
  //跳转到指南针界面
358
367
  RCT_EXPORT_METHOD(jumpCompassView) {
359
368
  dispatch_async(dispatch_get_main_queue(), ^{
360
- [[BDTBluetoothManager shared] jumpCompassView];
369
+ [[self bluetoothManager] jumpCompassView];
361
370
  });
362
371
  }
363
372
 
@@ -407,15 +416,133 @@ RCT_EXPORT_METHOD(getMessagesForPhone:(NSString *)phone
407
416
  RCT_EXPORT_METHOD(setBLEKey:(NSString *)bleKey
408
417
  resolve:(RCTPromiseResolveBlock)resolve
409
418
  rejecter:(RCTPromiseRejectBlock)reject) {
410
- [BDTBluetoothManager shared].bleKeyHex = bleKey;
419
+ [self bluetoothManager].bleKeyHex = bleKey;
411
420
  resolve(@(1)); // 可以返回任意值,表示成功
412
421
  }
413
422
 
423
+ RCT_EXPORT_METHOD(getContacts:(RCTPromiseResolveBlock)resolve
424
+ rejecter:(RCTPromiseRejectBlock)reject) {
425
+ CNAuthorizationStatus status = [CNContactStore authorizationStatusForEntityType:CNEntityTypeContacts];
426
+ CNContactStore *store = [[CNContactStore alloc] init];
427
+
428
+ void (^fetchContactsBlock)(void) = ^{
429
+ NSMutableArray *result = [NSMutableArray array];
430
+ NSArray *keysToFetch = @[
431
+ CNContactIdentifierKey,
432
+ CNContactGivenNameKey,
433
+ CNContactMiddleNameKey,
434
+ CNContactFamilyNameKey,
435
+ CNContactOrganizationNameKey,
436
+ CNContactPhoneNumbersKey
437
+ ];
438
+
439
+ CNContactFetchRequest *request = [[CNContactFetchRequest alloc] initWithKeysToFetch:keysToFetch];
440
+ request.sortOrder = CNContactSortOrderUserDefault;
441
+
442
+ NSError *fetchError = nil;
443
+ BOOL success = [store enumerateContactsWithFetchRequest:request
444
+ error:&fetchError
445
+ usingBlock:^(CNContact * _Nonnull contact, BOOL * _Nonnull stop) {
446
+ NSMutableOrderedSet *phonesSet = [NSMutableOrderedSet orderedSet];
447
+ for (CNLabeledValue<CNPhoneNumber *> *labeledValue in contact.phoneNumbers) {
448
+ NSString *rawNumber = labeledValue.value.stringValue ?: @"";
449
+ NSString *digits = [[rawNumber componentsSeparatedByCharactersInSet:[[NSCharacterSet decimalDigitCharacterSet] invertedSet]]
450
+ componentsJoinedByString:@""];
451
+ if (digits.length == 0) {
452
+ continue;
453
+ }
454
+ // 统一处理中国区号前缀,保持和业务侧11位手机号规则兼容
455
+ if ([digits hasPrefix:@"0086"] && digits.length > 11) {
456
+ digits = [digits substringFromIndex:4];
457
+ } else if ([digits hasPrefix:@"86"] && digits.length > 11) {
458
+ digits = [digits substringFromIndex:2];
459
+ }
460
+ if (digits.length == 0) {
461
+ continue;
462
+ }
463
+ [phonesSet addObject:digits];
464
+ }
465
+
466
+ if (phonesSet.count == 0) {
467
+ return;
468
+ }
469
+
470
+ NSString *name = [NSString stringWithFormat:@"%@%@%@",
471
+ contact.familyName ?: @"",
472
+ contact.middleName ?: @"",
473
+ contact.givenName ?: @""];
474
+ if (name.length == 0) {
475
+ name = contact.organizationName ?: @"";
476
+ }
477
+ if (name.length == 0) {
478
+ name = @"未知联系人";
479
+ }
480
+
481
+ NSMutableString *latin = [name mutableCopy];
482
+ CFStringTransform((__bridge CFMutableStringRef)latin, NULL, kCFStringTransformToLatin, NO);
483
+ latin = [[latin stringByFoldingWithOptions:NSDiacriticInsensitiveSearch
484
+ locale:[NSLocale currentLocale]] mutableCopy];
485
+
486
+ NSString *firstLetter = @"#";
487
+ if (latin.length > 0) {
488
+ NSString *c = [[latin substringToIndex:1] uppercaseString];
489
+ NSCharacterSet *letterSet = [NSCharacterSet characterSetWithCharactersInString:@"ABCDEFGHIJKLMNOPQRSTUVWXYZ"];
490
+ if ([c rangeOfCharacterFromSet:letterSet].location != NSNotFound) {
491
+ firstLetter = c;
492
+ }
493
+ }
494
+
495
+ NSDictionary *item = @{
496
+ @"id": contact.identifier ?: @"",
497
+ @"name": name,
498
+ @"firstLetter": firstLetter,
499
+ @"phoneNumbers": phonesSet.array
500
+ };
501
+ [result addObject:item];
502
+ }];
503
+
504
+ if (!success || fetchError) {
505
+ reject(@"CONTACTS_ERROR", fetchError.localizedDescription ?: @"读取通讯录失败", fetchError);
506
+ return;
507
+ }
508
+ resolve(result);
509
+ };
510
+
511
+ if (status == CNAuthorizationStatusAuthorized) {
512
+ fetchContactsBlock();
513
+ return;
514
+ }
515
+
516
+ if (status == CNAuthorizationStatusNotDetermined) {
517
+ [store requestAccessForEntityType:CNEntityTypeContacts completionHandler:^(BOOL granted, NSError * _Nullable error) {
518
+ dispatch_async(dispatch_get_main_queue(), ^{
519
+ if (error) {
520
+ reject(@"PERMISSION_ERROR", error.localizedDescription ?: @"通讯录权限请求失败", error);
521
+ return;
522
+ }
523
+ if (!granted) {
524
+ reject(@"PERMISSION_DENIED", @"缺少通讯录权限", nil);
525
+ return;
526
+ }
527
+ fetchContactsBlock();
528
+ });
529
+ }];
530
+ return;
531
+ }
532
+
533
+ if (status == CNAuthorizationStatusRestricted) {
534
+ reject(@"PERMISSION_RESTRICTED", @"通讯录权限受限", nil);
535
+ return;
536
+ }
537
+
538
+ reject(@"PERMISSION_DENIED", @"缺少通讯录权限", nil);
539
+ }
540
+
414
541
  /**
415
542
  判断蓝牙权限:0-未明确 1-受限的/未授权 2-拒绝 3-已授权
416
543
  */
417
544
  RCT_EXPORT_METHOD(initializeBluetooth:(RCTResponseSenderBlock)callBack){
418
- [[BDTBluetoothManager shared] getBluetoothAuthorizationStatus:^(NSString *status) {
545
+ [[self bluetoothManager] getBluetoothAuthorizationStatus:^(NSString *status) {
419
546
  callBack(@[status]);
420
547
  }];
421
548
  }
@@ -0,0 +1,14 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
+ <plist version="1.0">
4
+ <dict>
5
+ <key>NSPrivacyTracking</key>
6
+ <false/>
7
+ <key>NSPrivacyTrackingDomains</key>
8
+ <array/>
9
+ <key>NSPrivacyCollectedDataTypes</key>
10
+ <array/>
11
+ <key>NSPrivacyAccessedAPITypes</key>
12
+ <array/>
13
+ </dict>
14
+ </plist>
@@ -4,11 +4,15 @@
4
4
  <dict>
5
5
  <key>files</key>
6
6
  <dict>
7
- <key>FMDB_Privacy.bundle/Info.plist</key>
7
+ <key>.DS_Store</key>
8
8
  <data>
9
- WBxEhayK9LDcuBGPgDElRCnpskE=
9
+ cRXTcSAXZYQHOO3aez8s8FQBBYk=
10
10
  </data>
11
- <key>FMDB_Privacy.bundle/PrivacyInfo.xcprivacy</key>
11
+ <key>FMDB.bundle/Info.plist</key>
12
+ <data>
13
+ Rq8A+n6NWCkmlfKf7h7xU5ViHag=
14
+ </data>
15
+ <key>FMDB.bundle/PrivacyInfo.xcprivacy</key>
12
16
  <data>
13
17
  ucg9pita0v8d353x3NuGfxweQYU=
14
18
  </data>
@@ -34,7 +38,7 @@
34
38
  </data>
35
39
  <key>Info.plist</key>
36
40
  <data>
37
- wyYu4OM1CFn36F1aZLvvpdnzVkU=
41
+ B/ITQW6fj+Dc5Myk9CpAsQm3sdU=
38
42
  </data>
39
43
  <key>Modules/module.modulemap</key>
40
44
  <data>
@@ -43,23 +47,15 @@
43
47
  </dict>
44
48
  <key>files2</key>
45
49
  <dict>
46
- <key>FMDB_Privacy.bundle/Info.plist</key>
50
+ <key>FMDB.bundle/Info.plist</key>
47
51
  <dict>
48
- <key>hash</key>
49
- <data>
50
- WBxEhayK9LDcuBGPgDElRCnpskE=
51
- </data>
52
52
  <key>hash2</key>
53
53
  <data>
54
- 9SmgHWbqq7xIPq+R9Pt3UBnSpjJTszWfl88E+GH/Ea8=
54
+ Rmhe5qmUY/VTF2ntR5ylsGXvM5MdBUX8lGkf9J3DcWw=
55
55
  </data>
56
56
  </dict>
57
- <key>FMDB_Privacy.bundle/PrivacyInfo.xcprivacy</key>
57
+ <key>FMDB.bundle/PrivacyInfo.xcprivacy</key>
58
58
  <dict>
59
- <key>hash</key>
60
- <data>
61
- ucg9pita0v8d353x3NuGfxweQYU=
62
- </data>
63
59
  <key>hash2</key>
64
60
  <data>
65
61
  Uh6274Qwdz5cAQ4YOP6d2PpdYre3bRzqjX2NqtyxROI=
@@ -67,10 +63,6 @@
67
63
  </dict>
68
64
  <key>Headers/BDTBluetoothManager.h</key>
69
65
  <dict>
70
- <key>hash</key>
71
- <data>
72
- Mke3zeUQy40YfFrfW2gJ82VfWV4=
73
- </data>
74
66
  <key>hash2</key>
75
67
  <data>
76
68
  za/DfAgrjgS1qm3F78y6hNJPqscxWzIx+vD7ol+wERA=
@@ -78,10 +70,6 @@
78
70
  </dict>
79
71
  <key>Headers/BDTChatDBManager.h</key>
80
72
  <dict>
81
- <key>hash</key>
82
- <data>
83
- Ssm2BaxSbw5TyDQFFEvzaAIzti0=
84
- </data>
85
73
  <key>hash2</key>
86
74
  <data>
87
75
  TFMm6gfl9wRQMpzzFN3/sm1qAREjTDYKKfkUREEoOM8=
@@ -89,10 +77,6 @@
89
77
  </dict>
90
78
  <key>Headers/BDTDataPacketBuilder.h</key>
91
79
  <dict>
92
- <key>hash</key>
93
- <data>
94
- M2mub8VwH6cd3mT+Cmj6jU/wxfs=
95
- </data>
96
80
  <key>hash2</key>
97
81
  <data>
98
82
  HDzbJwP03m263UzurGCq5CnM2RmRkmJAvzRPsKAmZ9U=
@@ -100,10 +84,6 @@
100
84
  </dict>
101
85
  <key>Headers/BDTLocationService.h</key>
102
86
  <dict>
103
- <key>hash</key>
104
- <data>
105
- RzN/dKza3l/TAtgAS9ZuWVtxszs=
106
- </data>
107
87
  <key>hash2</key>
108
88
  <data>
109
89
  H3MgmiqqbNExoGreVNN3gPO81RCdL/r1NmAFF12PG4c=
@@ -111,10 +91,6 @@
111
91
  </dict>
112
92
  <key>Headers/BeidouBluetooth.h</key>
113
93
  <dict>
114
- <key>hash</key>
115
- <data>
116
- pjIaMEI7NmkpW/V7pIaOIcpW/8E=
117
- </data>
118
94
  <key>hash2</key>
119
95
  <data>
120
96
  7B/Mf1b1ApHkKh4ojqs364EJalW6lo6L8V3Bmv1gnvs=
@@ -122,10 +98,6 @@
122
98
  </dict>
123
99
  <key>Modules/module.modulemap</key>
124
100
  <dict>
125
- <key>hash</key>
126
- <data>
127
- yHOK7zkIIc74zmi9L/LHK2NDXUY=
128
- </data>
129
101
  <key>hash2</key>
130
102
  <data>
131
103
  2jYuzibwQKK2r2a2CS68WaFxOT/Tk941Kc8LUBwRUcg=
package/ios/CompassView.h CHANGED
@@ -14,6 +14,7 @@ NS_ASSUME_NONNULL_BEGIN
14
14
 
15
15
  /// RN 回调 block
16
16
  @property (nonatomic, copy) RCTBubblingEventBlock onHeadingChange;
17
+ @property (nonatomic, copy, nullable) void (^headingChangeHandler)(CGFloat radians, CGFloat degrees);
17
18
 
18
19
  @end
19
20
 
package/ios/CompassView.m CHANGED
@@ -68,6 +68,9 @@
68
68
  if (self.onHeadingChange) {
69
69
  self.onHeadingChange(@{@"radians": @(radians), @"degrees": @(magneticHeading)});
70
70
  }
71
+ if (self.headingChangeHandler) {
72
+ self.headingChangeHandler(radians, magneticHeading);
73
+ }
71
74
 
72
75
  });
73
76
  }
@@ -0,0 +1,11 @@
1
+ #ifdef RCT_NEW_ARCH_ENABLED
2
+ #import <React/RCTViewComponentView.h>
3
+ #import <UIKit/UIKit.h>
4
+
5
+ NS_ASSUME_NONNULL_BEGIN
6
+
7
+ @interface CompassViewComponentView : RCTViewComponentView
8
+ @end
9
+
10
+ NS_ASSUME_NONNULL_END
11
+ #endif