react-native-contacts 8.0.3 → 8.0.5
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.
- package/.tool-versions +1 -1
- package/README.md +10 -0
- package/android/src/main/java/com/rt2zz/reactnativecontacts/impl/ContactsManagerImpl.java +1336 -0
- package/android/src/newarch/com/rt2zz/reactnativecontacts/ContactsManager.java +25 -1139
- package/android/src/oldarch/com/rt2zz/reactnativecontacts/ContactsManager.java +24 -1135
- package/index.d.ts +88 -50
- package/index.ts +35 -3
- package/ios/RCTContacts/RCTContacts.mm +494 -161
- package/package.json +2 -2
- package/src/NativeContacts.ts +15 -1
- package/type.ts +6 -1
|
@@ -3,12 +3,9 @@
|
|
|
3
3
|
#import "RCTContacts.h"
|
|
4
4
|
#import <AssetsLibrary/AssetsLibrary.h>
|
|
5
5
|
#import <React/RCTLog.h>
|
|
6
|
+
#import <React/RCTUtils.h>
|
|
6
7
|
#import <Photos/Photos.h>
|
|
7
8
|
|
|
8
|
-
// #ifdef RCT_NEW_ARCH_ENABLED
|
|
9
|
-
// #import "RNContactsSpec.h"
|
|
10
|
-
// #endif
|
|
11
|
-
|
|
12
9
|
@implementation RCTContacts {
|
|
13
10
|
CNContactStore * contactStore;
|
|
14
11
|
|
|
@@ -56,24 +53,27 @@ RCT_REMAP_METHOD(getAll, withResolver:(RCTPromiseResolveBlock) resolve
|
|
|
56
53
|
}
|
|
57
54
|
|
|
58
55
|
|
|
59
|
-
RCT_EXPORT_METHOD(checkPermission:(RCTPromiseResolveBlock)
|
|
56
|
+
RCT_EXPORT_METHOD(checkPermission:(RCTPromiseResolveBlock)resolve
|
|
60
57
|
rejecter:(RCTPromiseRejectBlock) __unused reject)
|
|
61
58
|
{
|
|
62
59
|
CNAuthorizationStatus authStatus = [CNContactStore authorizationStatusForEntityType:CNEntityTypeContacts];
|
|
63
60
|
|
|
64
|
-
if (authStatus == CNAuthorizationStatusDenied || authStatus == CNAuthorizationStatusRestricted){
|
|
61
|
+
if (authStatus == CNAuthorizationStatusDenied || authStatus == CNAuthorizationStatusRestricted) {
|
|
65
62
|
resolve(@"denied");
|
|
66
|
-
} else if (authStatus == CNAuthorizationStatusAuthorized){
|
|
63
|
+
} else if (authStatus == CNAuthorizationStatusAuthorized) {
|
|
67
64
|
resolve(@"authorized");
|
|
68
|
-
} else if(@available(iOS 18, *)) {
|
|
69
|
-
if (authStatus ==
|
|
65
|
+
} else if (@available(iOS 18, *)) {
|
|
66
|
+
if (authStatus == CNAuthorizationStatusRestricted) {
|
|
70
67
|
resolve(@"limited");
|
|
68
|
+
} else {
|
|
69
|
+
resolve(@"undefined");
|
|
71
70
|
}
|
|
72
71
|
} else {
|
|
73
72
|
resolve(@"undefined");
|
|
74
73
|
}
|
|
75
74
|
}
|
|
76
75
|
|
|
76
|
+
|
|
77
77
|
RCT_EXPORT_METHOD(requestPermission:(RCTPromiseResolveBlock) resolve rejecter:(RCTPromiseRejectBlock) __unused reject)
|
|
78
78
|
{
|
|
79
79
|
CNContactStore* contactStore = [[CNContactStore alloc] init];
|
|
@@ -555,35 +555,34 @@ RCT_EXPORT_METHOD(getCount:(RCTPromiseResolveBlock) resolve rejecter:(RCTPromise
|
|
|
555
555
|
return [paths firstObject];
|
|
556
556
|
}
|
|
557
557
|
|
|
558
|
-
RCT_EXPORT_METHOD(getPhotoForId:(nonnull NSString *)recordID resolver:(RCTPromiseResolveBlock)
|
|
559
|
-
rejecter:(RCTPromiseRejectBlock)
|
|
558
|
+
RCT_EXPORT_METHOD(getPhotoForId:(nonnull NSString *)recordID resolver:(RCTPromiseResolveBlock)resolve
|
|
559
|
+
rejecter:(RCTPromiseRejectBlock)reject)
|
|
560
560
|
{
|
|
561
|
-
CNContactStore*
|
|
562
|
-
if(!contactStore)
|
|
561
|
+
CNContactStore *contactStore = [self contactsStore:reject];
|
|
562
|
+
if (!contactStore)
|
|
563
563
|
return;
|
|
564
564
|
|
|
565
565
|
CNEntityType entityType = CNEntityTypeContacts;
|
|
566
|
-
|
|
567
|
-
|
|
566
|
+
CNAuthorizationStatus authStatus = [CNContactStore authorizationStatusForEntityType:entityType];
|
|
567
|
+
|
|
568
|
+
if (authStatus == CNAuthorizationStatusNotDetermined) {
|
|
568
569
|
[contactStore requestAccessForEntityType:entityType completionHandler:^(BOOL granted, NSError * _Nullable error) {
|
|
569
|
-
if(granted){
|
|
570
|
+
if (granted) {
|
|
570
571
|
resolve([self getFilePathForThumbnailImage:recordID addressBook:contactStore]);
|
|
571
572
|
}
|
|
572
573
|
}];
|
|
573
|
-
}
|
|
574
|
-
else if([CNContactStore authorizationStatusForEntityType:entityType]== CNAuthorizationStatusAuthorized)
|
|
575
|
-
{
|
|
574
|
+
} else if (authStatus == CNAuthorizationStatusAuthorized) {
|
|
576
575
|
resolve([self getFilePathForThumbnailImage:recordID addressBook:contactStore]);
|
|
577
|
-
}
|
|
578
|
-
|
|
579
|
-
{
|
|
580
|
-
if([CNContactStore authorizationStatusForEntityType:entityType] == CNAuthorizationStatusLimited)
|
|
581
|
-
{
|
|
576
|
+
} else if (@available(iOS 18, *)) {
|
|
577
|
+
if (authStatus == CNAuthorizationStatusRestricted) {
|
|
582
578
|
resolve([self getFilePathForThumbnailImage:recordID addressBook:contactStore]);
|
|
583
579
|
}
|
|
580
|
+
} else {
|
|
581
|
+
reject(@"CONTACT_ACCESS_DENIED", @"Contact access is not authorized.", nil);
|
|
584
582
|
}
|
|
585
583
|
}
|
|
586
584
|
|
|
585
|
+
|
|
587
586
|
-(NSString *) getFilePathForThumbnailImage:(NSString *)recordID
|
|
588
587
|
addressBook:(CNContactStore*)addressBook
|
|
589
588
|
{
|
|
@@ -600,35 +599,36 @@ RCT_EXPORT_METHOD(getPhotoForId:(nonnull NSString *)recordID resolver:(RCTPromis
|
|
|
600
599
|
return [self getFilePathForThumbnailImage:contact recordID:recordID];
|
|
601
600
|
}
|
|
602
601
|
|
|
603
|
-
|
|
604
|
-
|
|
602
|
+
|
|
603
|
+
RCT_EXPORT_METHOD(getContactById:(nonnull NSString *)recordID resolver:(RCTPromiseResolveBlock)resolve
|
|
604
|
+
rejecter:(RCTPromiseRejectBlock)reject)
|
|
605
605
|
{
|
|
606
|
-
CNContactStore*
|
|
607
|
-
if(!contactStore)
|
|
606
|
+
CNContactStore *contactStore = [self contactsStore:reject];
|
|
607
|
+
if (!contactStore)
|
|
608
608
|
return;
|
|
609
609
|
|
|
610
610
|
CNEntityType entityType = CNEntityTypeContacts;
|
|
611
|
-
|
|
612
|
-
|
|
611
|
+
|
|
612
|
+
CNAuthorizationStatus authStatus = [CNContactStore authorizationStatusForEntityType:entityType];
|
|
613
|
+
|
|
614
|
+
if (authStatus == CNAuthorizationStatusNotDetermined) {
|
|
613
615
|
[contactStore requestAccessForEntityType:entityType completionHandler:^(BOOL granted, NSError * _Nullable error) {
|
|
614
|
-
if(granted){
|
|
615
|
-
resolve([self getContact:recordID addressBook:contactStore withThumbnails:
|
|
616
|
+
if (granted) {
|
|
617
|
+
resolve([self getContact:recordID addressBook:contactStore withThumbnails:NO]);
|
|
616
618
|
}
|
|
617
619
|
}];
|
|
618
|
-
}
|
|
619
|
-
|
|
620
|
-
{
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
else if(@available(iOS 18, *))
|
|
624
|
-
{
|
|
625
|
-
if([CNContactStore authorizationStatusForEntityType:entityType] == CNAuthorizationStatusLimited)
|
|
626
|
-
{
|
|
627
|
-
resolve([self getContact:recordID addressBook:contactStore withThumbnails:false]);
|
|
620
|
+
} else if (authStatus == CNAuthorizationStatusAuthorized) {
|
|
621
|
+
resolve([self getContact:recordID addressBook:contactStore withThumbnails:NO]);
|
|
622
|
+
} else if (@available(iOS 18, *)) {
|
|
623
|
+
if (authStatus == CNAuthorizationStatusRestricted) {
|
|
624
|
+
resolve([self getContact:recordID addressBook:contactStore withThumbnails:NO]);
|
|
628
625
|
}
|
|
626
|
+
} else {
|
|
627
|
+
reject(@"CONTACT_ACCESS_DENIED", @"Contact access is not authorized.", nil);
|
|
629
628
|
}
|
|
630
629
|
}
|
|
631
630
|
|
|
631
|
+
|
|
632
632
|
-(NSDictionary *) getContact:(NSString *)recordID
|
|
633
633
|
addressBook:(CNContactStore*)addressBook
|
|
634
634
|
withThumbnails:(BOOL) withThumbnails
|
|
@@ -687,7 +687,7 @@ RCT_EXPORT_METHOD(addContact:(NSDictionary *)contactData resolver:(RCTPromiseRes
|
|
|
687
687
|
}
|
|
688
688
|
}
|
|
689
689
|
|
|
690
|
-
RCT_EXPORT_METHOD(openContactForm:(NSDictionary *)contactData
|
|
690
|
+
RCT_EXPORT_METHOD(openContactForm:(NSDictionary *)contactData
|
|
691
691
|
resolver:(RCTPromiseResolveBlock) resolve
|
|
692
692
|
rejecter:(RCTPromiseRejectBlock) __unused reject)
|
|
693
693
|
{
|
|
@@ -702,12 +702,8 @@ RCT_EXPORT_METHOD(openContactForm:(NSDictionary *)contactData
|
|
|
702
702
|
|
|
703
703
|
dispatch_async(dispatch_get_main_queue(), ^{
|
|
704
704
|
UINavigationController* navigation = [[UINavigationController alloc] initWithRootViewController:controller];
|
|
705
|
-
UIViewController *
|
|
706
|
-
|
|
707
|
-
{
|
|
708
|
-
viewController = viewController.presentedViewController;
|
|
709
|
-
}
|
|
710
|
-
[viewController presentViewController:navigation animated:YES completion:nil];
|
|
705
|
+
UIViewController *presentingViewController = RCTPresentedViewController();
|
|
706
|
+
[presentingViewController presentViewController:navigation animated:YES completion:nil];
|
|
711
707
|
|
|
712
708
|
self->updateContactPromise = resolve;
|
|
713
709
|
});
|
|
@@ -759,7 +755,7 @@ RCT_EXPORT_METHOD(openExistingContact:(NSDictionary *)contactData resolver:(RCTP
|
|
|
759
755
|
activityIndicatorStyle = UIActivityIndicatorViewStyleMedium;
|
|
760
756
|
activityIndicatorBackgroundColor = [UIColor secondarySystemGroupedBackgroundColor];
|
|
761
757
|
} else {
|
|
762
|
-
activityIndicatorStyle =
|
|
758
|
+
activityIndicatorStyle = UIActivityIndicatorViewStyleMedium;
|
|
763
759
|
activityIndicatorBackgroundColor = [UIColor whiteColor];;
|
|
764
760
|
}
|
|
765
761
|
|
|
@@ -791,7 +787,7 @@ RCT_EXPORT_METHOD(openExistingContact:(NSDictionary *)contactData resolver:(RCTP
|
|
|
791
787
|
[activityIndicatorView removeFromSuperview];
|
|
792
788
|
});
|
|
793
789
|
|
|
794
|
-
updateContactPromise = resolve;
|
|
790
|
+
self->updateContactPromise = resolve;
|
|
795
791
|
});
|
|
796
792
|
|
|
797
793
|
}
|
|
@@ -831,15 +827,8 @@ RCT_EXPORT_METHOD(viewExistingContact:(NSDictionary *)contactData resolver:(RCTP
|
|
|
831
827
|
|
|
832
828
|
dispatch_async(dispatch_get_main_queue(), ^{
|
|
833
829
|
UINavigationController* navigation = [[UINavigationController alloc] initWithRootViewController:contactViewController];
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
while (currentViewController.presentedViewController)
|
|
838
|
-
{
|
|
839
|
-
currentViewController = currentViewController.presentedViewController;
|
|
840
|
-
}
|
|
841
|
-
|
|
842
|
-
[currentViewController presentViewController:navigation animated:YES completion:nil];
|
|
830
|
+
UIViewController *presentingViewController = RCTPresentedViewController();
|
|
831
|
+
[presentingViewController presentViewController:navigation animated:YES completion:nil];
|
|
843
832
|
|
|
844
833
|
updateContactPromise = resolve;
|
|
845
834
|
});
|
|
@@ -922,15 +911,8 @@ RCT_EXPORT_METHOD(editExistingContact:(NSDictionary *)contactData resolver:(RCTP
|
|
|
922
911
|
|
|
923
912
|
dispatch_async(dispatch_get_main_queue(), ^{
|
|
924
913
|
UINavigationController* navigation = [[UINavigationController alloc] initWithRootViewController:controller];
|
|
925
|
-
UIViewController *
|
|
926
|
-
|
|
927
|
-
//navigation.navigationBar.titleTextAttributes = @{NSForegroundColorAttributeName : [UIColor redColor]};
|
|
928
|
-
|
|
929
|
-
while (viewController.presentedViewController)
|
|
930
|
-
{
|
|
931
|
-
viewController = viewController.presentedViewController;
|
|
932
|
-
}
|
|
933
|
-
[viewController presentViewController:navigation animated:YES completion:nil];
|
|
914
|
+
UIViewController *presentingViewController = RCTPresentedViewController();
|
|
915
|
+
[presentingViewController presentViewController:navigation animated:YES completion:nil];
|
|
934
916
|
[controller presentViewController:alert animated:YES completion:nil];
|
|
935
917
|
|
|
936
918
|
self->updateContactPromise = resolve;
|
|
@@ -1250,7 +1232,7 @@ RCT_EXPORT_METHOD(deleteContact:(NSDictionary *)contactData resolver:(RCTPromise
|
|
|
1250
1232
|
}
|
|
1251
1233
|
|
|
1252
1234
|
RCT_EXPORT_METHOD(writePhotoToPath:(nonnull NSString *)path resolver:(RCTPromiseResolveBlock) resolve rejecter:(RCTPromiseRejectBlock) reject)
|
|
1253
|
-
{
|
|
1235
|
+
{
|
|
1254
1236
|
@try {
|
|
1255
1237
|
//Nothing is implemented here
|
|
1256
1238
|
} @catch (NSException *exception) {
|
|
@@ -1258,6 +1240,382 @@ RCT_EXPORT_METHOD(writePhotoToPath:(nonnull NSString *)path resolver:(RCTPromise
|
|
|
1258
1240
|
}
|
|
1259
1241
|
}
|
|
1260
1242
|
|
|
1243
|
+
RCT_EXPORT_METHOD(getGroups:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject)
|
|
1244
|
+
{
|
|
1245
|
+
if (!contactStore) {
|
|
1246
|
+
contactStore = [[CNContactStore alloc] init];
|
|
1247
|
+
}
|
|
1248
|
+
|
|
1249
|
+
NSError *error = nil;
|
|
1250
|
+
NSArray<CNGroup *> *groups = [contactStore groupsMatchingPredicate:nil error:&error];
|
|
1251
|
+
|
|
1252
|
+
if (error) {
|
|
1253
|
+
reject(@"get_groups_error", @"Failed to fetch groups", error);
|
|
1254
|
+
return;
|
|
1255
|
+
}
|
|
1256
|
+
|
|
1257
|
+
NSMutableArray *groupArray = [NSMutableArray array];
|
|
1258
|
+
for (CNGroup *group in groups) {
|
|
1259
|
+
NSDictionary *groupDict = @{
|
|
1260
|
+
@"identifier": group.identifier ?: @"",
|
|
1261
|
+
@"name": group.name ?: @""
|
|
1262
|
+
};
|
|
1263
|
+
[groupArray addObject:groupDict];
|
|
1264
|
+
}
|
|
1265
|
+
|
|
1266
|
+
resolve(groupArray);
|
|
1267
|
+
}
|
|
1268
|
+
RCT_EXPORT_METHOD(getGroup:(NSString *)identifier resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
|
|
1269
|
+
{
|
|
1270
|
+
CNContactStore *contactStore = [self contactsStore:reject];
|
|
1271
|
+
if (!contactStore) {
|
|
1272
|
+
// contactsStore method handles rejection
|
|
1273
|
+
return;
|
|
1274
|
+
}
|
|
1275
|
+
|
|
1276
|
+
NSError *error = nil;
|
|
1277
|
+
NSPredicate *predicate = [CNGroup predicateForGroupsWithIdentifiers:@[identifier]];
|
|
1278
|
+
NSArray<CNGroup *> *groups = [contactStore groupsMatchingPredicate:predicate error:&error];
|
|
1279
|
+
|
|
1280
|
+
if (error) {
|
|
1281
|
+
reject(@"get_group_error", @"Failed to fetch group", error);
|
|
1282
|
+
return;
|
|
1283
|
+
}
|
|
1284
|
+
|
|
1285
|
+
if (groups.count == 0) {
|
|
1286
|
+
reject(@"get_group_not_found", @"No group found with the given identifier", nil);
|
|
1287
|
+
return;
|
|
1288
|
+
}
|
|
1289
|
+
|
|
1290
|
+
CNGroup *group = groups.firstObject;
|
|
1291
|
+
NSDictionary *groupDict = @{
|
|
1292
|
+
@"identifier": group.identifier ?: @"",
|
|
1293
|
+
@"name": group.name ?: @""
|
|
1294
|
+
};
|
|
1295
|
+
|
|
1296
|
+
resolve(groupDict);
|
|
1297
|
+
}
|
|
1298
|
+
|
|
1299
|
+
RCT_EXPORT_METHOD(deleteGroup:(NSString *)identifier
|
|
1300
|
+
resolver:(RCTPromiseResolveBlock)resolve
|
|
1301
|
+
rejecter:(RCTPromiseRejectBlock)reject) {
|
|
1302
|
+
if (!contactStore) {
|
|
1303
|
+
contactStore = [[CNContactStore alloc] init];
|
|
1304
|
+
}
|
|
1305
|
+
|
|
1306
|
+
NSError *error = nil;
|
|
1307
|
+
NSPredicate *predicate = [CNGroup predicateForGroupsWithIdentifiers:@[identifier]];
|
|
1308
|
+
NSArray<CNGroup *> *groups = [contactStore groupsMatchingPredicate:predicate error:&error];
|
|
1309
|
+
|
|
1310
|
+
if (error) {
|
|
1311
|
+
reject(@"delete_group_error", @"Failed to fetch group", error);
|
|
1312
|
+
return;
|
|
1313
|
+
}
|
|
1314
|
+
|
|
1315
|
+
if (groups.count == 0) {
|
|
1316
|
+
reject(@"delete_group_not_found", @"No group found with the given identifier", nil);
|
|
1317
|
+
return;
|
|
1318
|
+
}
|
|
1319
|
+
|
|
1320
|
+
CNGroup *groupToDelete = groups.firstObject;
|
|
1321
|
+
CNMutableGroup *mutableGroup = [groupToDelete mutableCopy];
|
|
1322
|
+
CNSaveRequest *saveRequest = [[CNSaveRequest alloc] init];
|
|
1323
|
+
[saveRequest deleteGroup:mutableGroup];
|
|
1324
|
+
|
|
1325
|
+
BOOL success = [contactStore executeSaveRequest:saveRequest error:&error];
|
|
1326
|
+
|
|
1327
|
+
if (success) {
|
|
1328
|
+
resolve(@(YES));
|
|
1329
|
+
} else {
|
|
1330
|
+
reject(@"delete_group_failed", @"Failed to delete group", error);
|
|
1331
|
+
}
|
|
1332
|
+
}
|
|
1333
|
+
|
|
1334
|
+
RCT_EXPORT_METHOD(updateGroup:(NSString *)identifier
|
|
1335
|
+
groupData:(NSDictionary *)groupData
|
|
1336
|
+
resolver:(RCTPromiseResolveBlock)resolve
|
|
1337
|
+
rejecter:(RCTPromiseRejectBlock)reject)
|
|
1338
|
+
{
|
|
1339
|
+
if (!contactStore) {
|
|
1340
|
+
contactStore = [[CNContactStore alloc] init];
|
|
1341
|
+
}
|
|
1342
|
+
|
|
1343
|
+
NSError *error = nil;
|
|
1344
|
+
NSPredicate *predicate = [CNGroup predicateForGroupsWithIdentifiers:@[identifier]];
|
|
1345
|
+
NSArray<CNGroup *> *groups = [contactStore groupsMatchingPredicate:predicate error:&error];
|
|
1346
|
+
|
|
1347
|
+
if (error) {
|
|
1348
|
+
reject(@"update_group_error", @"Failed to fetch group", error);
|
|
1349
|
+
return;
|
|
1350
|
+
}
|
|
1351
|
+
|
|
1352
|
+
if (groups.count == 0) {
|
|
1353
|
+
reject(@"update_group_not_found", @"No group found with the given identifier", nil);
|
|
1354
|
+
return;
|
|
1355
|
+
}
|
|
1356
|
+
|
|
1357
|
+
CNGroup *groupToUpdate = groups.firstObject;
|
|
1358
|
+
CNMutableGroup *mutableGroup = [groupToUpdate mutableCopy];
|
|
1359
|
+
|
|
1360
|
+
// Update group details based on groupData
|
|
1361
|
+
NSString *newName = groupData[@"name"];
|
|
1362
|
+
if (newName && [newName isKindOfClass:[NSString class]] && newName.length > 0) {
|
|
1363
|
+
mutableGroup.name = newName;
|
|
1364
|
+
}
|
|
1365
|
+
|
|
1366
|
+
CNSaveRequest *saveRequest = [[CNSaveRequest alloc] init];
|
|
1367
|
+
[saveRequest updateGroup:mutableGroup];
|
|
1368
|
+
|
|
1369
|
+
BOOL success = [contactStore executeSaveRequest:saveRequest error:&error];
|
|
1370
|
+
|
|
1371
|
+
if (success) {
|
|
1372
|
+
NSDictionary *updatedGroupDict = @{
|
|
1373
|
+
@"identifier": mutableGroup.identifier ?: @"",
|
|
1374
|
+
@"name": mutableGroup.name ?: @""
|
|
1375
|
+
};
|
|
1376
|
+
resolve(updatedGroupDict);
|
|
1377
|
+
} else {
|
|
1378
|
+
reject(@"update_group_failed", @"Failed to update group", error);
|
|
1379
|
+
}
|
|
1380
|
+
}
|
|
1381
|
+
|
|
1382
|
+
RCT_EXPORT_METHOD(addGroup:(NSDictionary *)groupData
|
|
1383
|
+
resolver:(RCTPromiseResolveBlock)resolve
|
|
1384
|
+
rejecter:(RCTPromiseRejectBlock)reject)
|
|
1385
|
+
{
|
|
1386
|
+
if (!groupData || ![groupData isKindOfClass:[NSDictionary class]]) {
|
|
1387
|
+
reject(@"invalid_data", @"Group data must be a dictionary", nil);
|
|
1388
|
+
return;
|
|
1389
|
+
}
|
|
1390
|
+
|
|
1391
|
+
NSString *groupName = groupData[@"name"];
|
|
1392
|
+
if (!groupName || ![groupName isKindOfClass:[NSString class]] || groupName.length == 0) {
|
|
1393
|
+
reject(@"invalid_name", @"Group name is required and must be a non-empty string", nil);
|
|
1394
|
+
return;
|
|
1395
|
+
}
|
|
1396
|
+
|
|
1397
|
+
CNContactStore *store = [self contactsStore:reject];
|
|
1398
|
+
if (!store) {
|
|
1399
|
+
// contactsStore method handles rejection
|
|
1400
|
+
return;
|
|
1401
|
+
}
|
|
1402
|
+
|
|
1403
|
+
CNMutableGroup *mutableGroup = [[CNMutableGroup alloc] init];
|
|
1404
|
+
mutableGroup.name = groupName;
|
|
1405
|
+
|
|
1406
|
+
CNSaveRequest *saveRequest = [[CNSaveRequest alloc] init];
|
|
1407
|
+
[saveRequest addGroup:mutableGroup toContainerWithIdentifier:nil]; // Add to default container
|
|
1408
|
+
|
|
1409
|
+
NSError *error = nil;
|
|
1410
|
+
BOOL success = [store executeSaveRequest:saveRequest error:&error];
|
|
1411
|
+
if (success) {
|
|
1412
|
+
NSDictionary *groupDict = @{
|
|
1413
|
+
@"identifier": mutableGroup.identifier ?: @"",
|
|
1414
|
+
@"name": mutableGroup.name ?: @""
|
|
1415
|
+
};
|
|
1416
|
+
resolve(groupDict);
|
|
1417
|
+
} else {
|
|
1418
|
+
NSString *errorMessage = error.localizedDescription ?: @"Unknown error adding group";
|
|
1419
|
+
reject(@"add_group_error", errorMessage, error);
|
|
1420
|
+
}
|
|
1421
|
+
}
|
|
1422
|
+
|
|
1423
|
+
RCT_EXPORT_METHOD(contactsInGroup:(NSString *)identifier
|
|
1424
|
+
resolver:(RCTPromiseResolveBlock)resolve
|
|
1425
|
+
rejecter:(RCTPromiseRejectBlock)reject)
|
|
1426
|
+
{
|
|
1427
|
+
CNContactStore *store = [self contactsStore:reject];
|
|
1428
|
+
if (!store) {
|
|
1429
|
+
return;
|
|
1430
|
+
}
|
|
1431
|
+
|
|
1432
|
+
NSError *error = nil;
|
|
1433
|
+
NSPredicate *predicate = [CNContact predicateForContactsInGroupWithIdentifier:identifier];
|
|
1434
|
+
NSArray *keysToFetch = @[
|
|
1435
|
+
CNContactIdentifierKey,
|
|
1436
|
+
CNContactGivenNameKey,
|
|
1437
|
+
CNContactFamilyNameKey,
|
|
1438
|
+
CNContactMiddleNameKey,
|
|
1439
|
+
CNContactEmailAddressesKey,
|
|
1440
|
+
CNContactPhoneNumbersKey,
|
|
1441
|
+
CNContactPostalAddressesKey,
|
|
1442
|
+
CNContactOrganizationNameKey,
|
|
1443
|
+
CNContactJobTitleKey,
|
|
1444
|
+
CNContactImageDataAvailableKey,
|
|
1445
|
+
CNContactThumbnailImageDataKey,
|
|
1446
|
+
CNContactUrlAddressesKey,
|
|
1447
|
+
CNContactBirthdayKey,
|
|
1448
|
+
CNContactInstantMessageAddressesKey
|
|
1449
|
+
];
|
|
1450
|
+
|
|
1451
|
+
if (notesUsageEnabled) {
|
|
1452
|
+
keysToFetch = [keysToFetch arrayByAddingObject:CNContactNoteKey];
|
|
1453
|
+
}
|
|
1454
|
+
|
|
1455
|
+
CNContactFetchRequest *fetchRequest = [[CNContactFetchRequest alloc] initWithKeysToFetch:keysToFetch];
|
|
1456
|
+
fetchRequest.predicate = predicate;
|
|
1457
|
+
|
|
1458
|
+
NSMutableArray *contacts = [NSMutableArray array];
|
|
1459
|
+
|
|
1460
|
+
BOOL success = [store enumerateContactsWithFetchRequest:fetchRequest error:&error usingBlock:^(CNContact * _Nonnull contact, BOOL * _Nonnull stop) {
|
|
1461
|
+
NSDictionary *contactDict = [self contactToDictionary:contact withThumbnails:true];
|
|
1462
|
+
[contacts addObject:contactDict];
|
|
1463
|
+
}];
|
|
1464
|
+
|
|
1465
|
+
if (!success) {
|
|
1466
|
+
reject(@"contacts_in_group_error", @"Failed to fetch contacts in group", error);
|
|
1467
|
+
return;
|
|
1468
|
+
}
|
|
1469
|
+
|
|
1470
|
+
resolve(contacts);
|
|
1471
|
+
}
|
|
1472
|
+
|
|
1473
|
+
RCT_EXPORT_METHOD(addContactsToGroup:(NSString *)groupId
|
|
1474
|
+
contactIds:(NSArray<NSString *> *)contactIds
|
|
1475
|
+
resolver:(RCTPromiseResolveBlock)resolve
|
|
1476
|
+
rejecter:(RCTPromiseRejectBlock)reject)
|
|
1477
|
+
{
|
|
1478
|
+
// Ensure contactStore is initialized
|
|
1479
|
+
if (!contactStore) {
|
|
1480
|
+
contactStore = [[CNContactStore alloc] init];
|
|
1481
|
+
}
|
|
1482
|
+
|
|
1483
|
+
// Check authorization
|
|
1484
|
+
CNAuthorizationStatus authStatus = [CNContactStore authorizationStatusForEntityType:CNEntityTypeContacts];
|
|
1485
|
+
if (@available(iOS 18.0, *)) {
|
|
1486
|
+
if (authStatus != CNAuthorizationStatusAuthorized && authStatus != CNAuthorizationStatusLimited) {
|
|
1487
|
+
reject(@"permission_denied", @"Contacts permission denied", nil);
|
|
1488
|
+
return;
|
|
1489
|
+
}
|
|
1490
|
+
}
|
|
1491
|
+
else if (authStatus != CNAuthorizationStatusAuthorized) {
|
|
1492
|
+
reject(@"permission_denied", @"Contacts permission denied", nil);
|
|
1493
|
+
return;
|
|
1494
|
+
}
|
|
1495
|
+
|
|
1496
|
+
NSError *error = nil;
|
|
1497
|
+
|
|
1498
|
+
// Fetch the group
|
|
1499
|
+
NSPredicate *predicate = [CNGroup predicateForGroupsWithIdentifiers:@[groupId]];
|
|
1500
|
+
NSArray<CNGroup *> *groups = [contactStore groupsMatchingPredicate:predicate error:&error];
|
|
1501
|
+
|
|
1502
|
+
if (error) {
|
|
1503
|
+
reject(@"group_fetch_error", @"Failed to fetch group", error);
|
|
1504
|
+
return;
|
|
1505
|
+
}
|
|
1506
|
+
|
|
1507
|
+
if (groups.count == 0) {
|
|
1508
|
+
reject(@"group_not_found", @"No group found with the given identifier", nil);
|
|
1509
|
+
return;
|
|
1510
|
+
}
|
|
1511
|
+
|
|
1512
|
+
CNGroup *group = groups.firstObject;
|
|
1513
|
+
|
|
1514
|
+
// Initialize CNSaveRequest
|
|
1515
|
+
CNSaveRequest *saveRequest = [[CNSaveRequest alloc] init];
|
|
1516
|
+
|
|
1517
|
+
// Iterate over contactIds and add each contact to the group
|
|
1518
|
+
for (NSString *contactId in contactIds) {
|
|
1519
|
+
// Fetch the contact
|
|
1520
|
+
NSError *contactError = nil;
|
|
1521
|
+
CNContact *contact = [contactStore unifiedContactWithIdentifier:contactId
|
|
1522
|
+
keysToFetch:@[CNContactIdentifierKey]
|
|
1523
|
+
error:&contactError];
|
|
1524
|
+
if (contactError) {
|
|
1525
|
+
reject(@"contact_fetch_error", [NSString stringWithFormat:@"Failed to fetch contact with ID %@", contactId], contactError);
|
|
1526
|
+
return;
|
|
1527
|
+
}
|
|
1528
|
+
|
|
1529
|
+
if (!contact) {
|
|
1530
|
+
reject(@"contact_not_found", [NSString stringWithFormat:@"No contact found with ID %@", contactId], nil);
|
|
1531
|
+
return;
|
|
1532
|
+
}
|
|
1533
|
+
|
|
1534
|
+
// Add contact to group
|
|
1535
|
+
[saveRequest addMember:contact toGroup:group];
|
|
1536
|
+
}
|
|
1537
|
+
|
|
1538
|
+
// Execute the save request
|
|
1539
|
+
BOOL success = [contactStore executeSaveRequest:saveRequest error:&error];
|
|
1540
|
+
|
|
1541
|
+
if (success) {
|
|
1542
|
+
resolve(@(YES));
|
|
1543
|
+
} else {
|
|
1544
|
+
reject(@"add_contacts_error", @"Failed to add contacts to group", error);
|
|
1545
|
+
}
|
|
1546
|
+
}
|
|
1547
|
+
|
|
1548
|
+
RCT_EXPORT_METHOD(removeContactsFromGroup:(NSString *)groupId
|
|
1549
|
+
contactIds:(NSArray<NSString *> *)contactIds
|
|
1550
|
+
resolver:(RCTPromiseResolveBlock)resolve
|
|
1551
|
+
rejecter:(RCTPromiseRejectBlock)reject) {
|
|
1552
|
+
// Ensure contactStore is initialized
|
|
1553
|
+
if (!contactStore) {
|
|
1554
|
+
contactStore = [[CNContactStore alloc] init];
|
|
1555
|
+
}
|
|
1556
|
+
|
|
1557
|
+
// Check authorization status
|
|
1558
|
+
CNAuthorizationStatus authStatus = [CNContactStore authorizationStatusForEntityType:CNEntityTypeContacts];
|
|
1559
|
+
if (@available(iOS 18.0, *)) {
|
|
1560
|
+
if (authStatus != CNAuthorizationStatusAuthorized && authStatus != CNAuthorizationStatusLimited) {
|
|
1561
|
+
reject(@"permission_denied", @"Contacts permission denied", nil);
|
|
1562
|
+
return;
|
|
1563
|
+
}
|
|
1564
|
+
}
|
|
1565
|
+
else if (authStatus != CNAuthorizationStatusAuthorized) {
|
|
1566
|
+
reject(@"permission_denied", @"Contacts permission denied", nil);
|
|
1567
|
+
return;
|
|
1568
|
+
}
|
|
1569
|
+
|
|
1570
|
+
// Fetch the group
|
|
1571
|
+
NSError *error = nil;
|
|
1572
|
+
NSPredicate *predicate = [CNGroup predicateForGroupsWithIdentifiers:@[groupId]];
|
|
1573
|
+
NSArray<CNGroup *> *groups = [contactStore groupsMatchingPredicate:predicate error:&error];
|
|
1574
|
+
|
|
1575
|
+
if (error) {
|
|
1576
|
+
reject(@"group_fetch_error", @"Failed to fetch group", error);
|
|
1577
|
+
return;
|
|
1578
|
+
}
|
|
1579
|
+
|
|
1580
|
+
if (groups.count == 0) {
|
|
1581
|
+
reject(@"group_not_found", @"No group found with the given identifier", nil);
|
|
1582
|
+
return;
|
|
1583
|
+
}
|
|
1584
|
+
|
|
1585
|
+
CNGroup *group = groups.firstObject;
|
|
1586
|
+
CNMutableGroup *mutableGroup = [group mutableCopy];
|
|
1587
|
+
CNSaveRequest *saveRequest = [[CNSaveRequest alloc] init];
|
|
1588
|
+
|
|
1589
|
+
// Iterate over contactIds and remove each contact from the group
|
|
1590
|
+
for (NSString *contactId in contactIds) {
|
|
1591
|
+
NSError *contactError = nil;
|
|
1592
|
+
CNContact *contact = [contactStore unifiedContactWithIdentifier:contactId
|
|
1593
|
+
keysToFetch:@[CNContactIdentifierKey]
|
|
1594
|
+
error:&contactError];
|
|
1595
|
+
if (contactError) {
|
|
1596
|
+
reject(@"contact_fetch_error", [NSString stringWithFormat:@"Failed to fetch contact with ID %@", contactId], contactError);
|
|
1597
|
+
return;
|
|
1598
|
+
}
|
|
1599
|
+
|
|
1600
|
+
if (!contact) {
|
|
1601
|
+
reject(@"contact_not_found", [NSString stringWithFormat:@"No contact found with ID %@", contactId], nil);
|
|
1602
|
+
return;
|
|
1603
|
+
}
|
|
1604
|
+
|
|
1605
|
+
[saveRequest removeMember:contact fromGroup:mutableGroup];
|
|
1606
|
+
}
|
|
1607
|
+
|
|
1608
|
+
// Execute the save request
|
|
1609
|
+
BOOL success = [contactStore executeSaveRequest:saveRequest error:&error];
|
|
1610
|
+
|
|
1611
|
+
if (success) {
|
|
1612
|
+
resolve(@(YES));
|
|
1613
|
+
} else {
|
|
1614
|
+
reject(@"remove_contacts_error", @"Failed to remove contacts from group", error);
|
|
1615
|
+
}
|
|
1616
|
+
}
|
|
1617
|
+
|
|
1618
|
+
|
|
1261
1619
|
-(CNContactStore*) contactsStore: (RCTPromiseRejectBlock) reject {
|
|
1262
1620
|
if(!contactStore) {
|
|
1263
1621
|
CNContactStore* store = [[CNContactStore alloc] init];
|
|
@@ -1295,24 +1653,25 @@ RCT_EXPORT_METHOD(writePhotoToPath:(nonnull NSString *)path resolver:(RCTPromise
|
|
|
1295
1653
|
|
|
1296
1654
|
#endif
|
|
1297
1655
|
|
|
1298
|
-
- (void)getAll:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject {
|
|
1656
|
+
- (void)getAll:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject {
|
|
1299
1657
|
[self getAllContacts:resolve reject:reject withThumbnails:true];
|
|
1300
1658
|
}
|
|
1301
1659
|
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1660
|
+
- (void)checkPermission:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject {
|
|
1661
|
+
CNAuthorizationStatus authStatus = [CNContactStore authorizationStatusForEntityType:CNEntityTypeContacts];
|
|
1662
|
+
|
|
1663
|
+
if (authStatus == CNAuthorizationStatusDenied || authStatus == CNAuthorizationStatusRestricted) {
|
|
1664
|
+
resolve(@"denied");
|
|
1665
|
+
} else if (authStatus == CNAuthorizationStatusAuthorized) {
|
|
1666
|
+
resolve(@"authorized");
|
|
1667
|
+
} else if (@available(iOS 18, *)) {
|
|
1668
|
+
if (authStatus == CNAuthorizationStatusRestricted) {
|
|
1669
|
+
resolve(@"limited");
|
|
1670
|
+
}
|
|
1671
|
+
} else {
|
|
1672
|
+
resolve(@"undefined");
|
|
1673
|
+
}
|
|
1674
|
+
}
|
|
1316
1675
|
|
|
1317
1676
|
|
|
1318
1677
|
- (void)deleteContact:(NSDictionary *)contactData resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject {
|
|
@@ -1411,15 +1770,8 @@ RCT_EXPORT_METHOD(writePhotoToPath:(nonnull NSString *)path resolver:(RCTPromise
|
|
|
1411
1770
|
|
|
1412
1771
|
dispatch_async(dispatch_get_main_queue(), ^{
|
|
1413
1772
|
UINavigationController* navigation = [[UINavigationController alloc] initWithRootViewController:controller];
|
|
1414
|
-
UIViewController *
|
|
1415
|
-
|
|
1416
|
-
//navigation.navigationBar.titleTextAttributes = @{NSForegroundColorAttributeName : [UIColor redColor]};
|
|
1417
|
-
|
|
1418
|
-
while (viewController.presentedViewController)
|
|
1419
|
-
{
|
|
1420
|
-
viewController = viewController.presentedViewController;
|
|
1421
|
-
}
|
|
1422
|
-
[viewController presentViewController:navigation animated:YES completion:nil];
|
|
1773
|
+
UIViewController *presentingViewController = RCTPresentedViewController();
|
|
1774
|
+
[presentingViewController presentViewController:navigation animated:YES completion:nil];
|
|
1423
1775
|
[controller presentViewController:alert animated:YES completion:nil];
|
|
1424
1776
|
|
|
1425
1777
|
self->updateContactPromise = resolve;
|
|
@@ -1440,37 +1792,33 @@ RCT_EXPORT_METHOD(writePhotoToPath:(nonnull NSString *)path resolver:(RCTPromise
|
|
|
1440
1792
|
}
|
|
1441
1793
|
|
|
1442
1794
|
|
|
1443
|
-
- (void)getAllWithoutPhotos:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject {
|
|
1795
|
+
- (void)getAllWithoutPhotos:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject {
|
|
1444
1796
|
[self getAllContacts:resolve reject:reject withThumbnails:false];
|
|
1445
1797
|
}
|
|
1446
1798
|
|
|
1447
1799
|
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1800
|
+
- (void)getContactById:(nonnull NSString *)recordID resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject {
|
|
1801
|
+
CNContactStore *contactStore = [self contactsStore:reject];
|
|
1802
|
+
if (!contactStore)
|
|
1803
|
+
return;
|
|
1452
1804
|
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
{
|
|
1468
|
-
if([CNContactStore authorizationStatusForEntityType:entityType] == CNAuthorizationStatusLimited)
|
|
1469
|
-
{
|
|
1470
|
-
resolve([self getContact:recordID addressBook:contactStore withThumbnails:false]);
|
|
1805
|
+
CNEntityType entityType = CNEntityTypeContacts;
|
|
1806
|
+
CNAuthorizationStatus authorizationStatus = [CNContactStore authorizationStatusForEntityType:entityType];
|
|
1807
|
+
|
|
1808
|
+
if (authorizationStatus == CNAuthorizationStatusNotDetermined) {
|
|
1809
|
+
[contactStore requestAccessForEntityType:entityType completionHandler:^(BOOL granted, NSError * _Nullable error) {
|
|
1810
|
+
if (granted) {
|
|
1811
|
+
resolve([self getContact:recordID addressBook:contactStore withThumbnails:NO]);
|
|
1812
|
+
}
|
|
1813
|
+
}];
|
|
1814
|
+
} else if (authorizationStatus == CNAuthorizationStatusAuthorized) {
|
|
1815
|
+
resolve([self getContact:recordID addressBook:contactStore withThumbnails:NO]);
|
|
1816
|
+
} else if (@available(iOS 18, *)) {
|
|
1817
|
+
if (authorizationStatus == CNAuthorizationStatusRestricted) {
|
|
1818
|
+
resolve([self getContact:recordID addressBook:contactStore withThumbnails:NO]);
|
|
1471
1819
|
}
|
|
1472
|
-
|
|
1473
|
-
|
|
1820
|
+
}
|
|
1821
|
+
}
|
|
1474
1822
|
|
|
1475
1823
|
|
|
1476
1824
|
- (void)getContactsByEmailAddress:(NSString *)string resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject {
|
|
@@ -1497,39 +1845,35 @@ RCT_EXPORT_METHOD(writePhotoToPath:(nonnull NSString *)path resolver:(RCTPromise
|
|
|
1497
1845
|
}
|
|
1498
1846
|
|
|
1499
1847
|
|
|
1500
|
-
- (void)getCount:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject {
|
|
1848
|
+
- (void)getCount:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject {
|
|
1501
1849
|
[self getAllContactsCount:resolve reject:reject];
|
|
1502
1850
|
}
|
|
1503
1851
|
|
|
1504
1852
|
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1853
|
+
- (void)getPhotoForId:(nonnull NSString *)recordID resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject {
|
|
1854
|
+
CNContactStore *contactStore = [self contactsStore:reject];
|
|
1855
|
+
if (!contactStore)
|
|
1856
|
+
return;
|
|
1509
1857
|
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
}
|
|
1517
|
-
}];
|
|
1518
|
-
}
|
|
1519
|
-
else if([CNContactStore authorizationStatusForEntityType:entityType]== CNAuthorizationStatusAuthorized)
|
|
1520
|
-
{
|
|
1521
|
-
resolve([self getFilePathForThumbnailImage:recordID addressBook:contactStore]);
|
|
1522
|
-
}
|
|
1523
|
-
else if(@available(iOS 18, *))
|
|
1524
|
-
{
|
|
1525
|
-
if([CNContactStore authorizationStatusForEntityType:entityType] == CNAuthorizationStatusLimited)
|
|
1526
|
-
{
|
|
1858
|
+
CNEntityType entityType = CNEntityTypeContacts;
|
|
1859
|
+
CNAuthorizationStatus authStatus = [CNContactStore authorizationStatusForEntityType:entityType];
|
|
1860
|
+
|
|
1861
|
+
if (authStatus == CNAuthorizationStatusNotDetermined) {
|
|
1862
|
+
[contactStore requestAccessForEntityType:entityType completionHandler:^(BOOL granted, NSError * _Nullable error) {
|
|
1863
|
+
if (granted) {
|
|
1527
1864
|
resolve([self getFilePathForThumbnailImage:recordID addressBook:contactStore]);
|
|
1528
1865
|
}
|
|
1529
|
-
|
|
1866
|
+
}];
|
|
1867
|
+
} else if (authStatus == CNAuthorizationStatusAuthorized) {
|
|
1868
|
+
resolve([self getFilePathForThumbnailImage:recordID addressBook:contactStore]);
|
|
1869
|
+
} else if (@available(iOS 18, *)) {
|
|
1870
|
+
if (authStatus == CNAuthorizationStatusRestricted) {
|
|
1871
|
+
resolve([self getFilePathForThumbnailImage:recordID addressBook:contactStore]);
|
|
1530
1872
|
}
|
|
1531
|
-
|
|
1532
|
-
|
|
1873
|
+
} else {
|
|
1874
|
+
reject(@"CONTACT_ACCESS_DENIED", @"Contact access is not authorized.", nil);
|
|
1875
|
+
}
|
|
1876
|
+
}
|
|
1533
1877
|
|
|
1534
1878
|
- (void)openContactForm:(NSDictionary *)contactData resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject {
|
|
1535
1879
|
CNMutableContact * contact = [[CNMutableContact alloc] init];
|
|
@@ -1543,12 +1887,8 @@ RCT_EXPORT_METHOD(writePhotoToPath:(nonnull NSString *)path resolver:(RCTPromise
|
|
|
1543
1887
|
|
|
1544
1888
|
dispatch_async(dispatch_get_main_queue(), ^{
|
|
1545
1889
|
UINavigationController* navigation = [[UINavigationController alloc] initWithRootViewController:controller];
|
|
1546
|
-
UIViewController *
|
|
1547
|
-
|
|
1548
|
-
{
|
|
1549
|
-
viewController = viewController.presentedViewController;
|
|
1550
|
-
}
|
|
1551
|
-
[viewController presentViewController:navigation animated:YES completion:nil];
|
|
1890
|
+
UIViewController *presentingViewController = RCTPresentedViewController();
|
|
1891
|
+
[presentingViewController presentViewController:navigation animated:YES completion:nil];
|
|
1552
1892
|
|
|
1553
1893
|
self->updateContactPromise = resolve;
|
|
1554
1894
|
});
|
|
@@ -1641,7 +1981,7 @@ RCT_EXPORT_METHOD(writePhotoToPath:(nonnull NSString *)path resolver:(RCTPromise
|
|
|
1641
1981
|
}
|
|
1642
1982
|
|
|
1643
1983
|
|
|
1644
|
-
- (void)requestPermission:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject {
|
|
1984
|
+
- (void)requestPermission:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject {
|
|
1645
1985
|
CNContactStore* contactStore = [[CNContactStore alloc] init];
|
|
1646
1986
|
|
|
1647
1987
|
[contactStore requestAccessForEntityType:CNEntityTypeContacts completionHandler:^(BOOL granted, NSError * _Nullable error) {
|
|
@@ -1724,15 +2064,8 @@ RCT_EXPORT_METHOD(writePhotoToPath:(nonnull NSString *)path resolver:(RCTPromise
|
|
|
1724
2064
|
|
|
1725
2065
|
dispatch_async(dispatch_get_main_queue(), ^{
|
|
1726
2066
|
UINavigationController* navigation = [[UINavigationController alloc] initWithRootViewController:contactViewController];
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
while (currentViewController.presentedViewController)
|
|
1731
|
-
{
|
|
1732
|
-
currentViewController = currentViewController.presentedViewController;
|
|
1733
|
-
}
|
|
1734
|
-
|
|
1735
|
-
[currentViewController presentViewController:navigation animated:YES completion:nil];
|
|
2067
|
+
UIViewController *presentingViewController = RCTPresentedViewController();
|
|
2068
|
+
[presentingViewController presentViewController:navigation animated:YES completion:nil];
|
|
1736
2069
|
|
|
1737
2070
|
updateContactPromise = resolve;
|
|
1738
2071
|
});
|
|
@@ -1744,7 +2077,7 @@ RCT_EXPORT_METHOD(writePhotoToPath:(nonnull NSString *)path resolver:(RCTPromise
|
|
|
1744
2077
|
}
|
|
1745
2078
|
|
|
1746
2079
|
|
|
1747
|
-
- (void)writePhotoToPath:(NSString *)contactId file:(NSString *)file resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject {
|
|
2080
|
+
- (void)writePhotoToPath:(NSString *)contactId file:(NSString *)file resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject {
|
|
1748
2081
|
reject(@"Error", @"not implemented", nil);
|
|
1749
2082
|
}
|
|
1750
2083
|
|