简体   繁体   中英

iOS App crashes when accessing a contact from Exchange Global Address List

I have an application build up on cordova framework and I'm using a plugin called cordova-plugin-contacts ( https://github.com/apache/cordova-plugin-contacts ) in order to access the number of a contact.

Whenever I choose a contact from my contacts, the number of the contact is picked up properly in both iOS 9 and 10. However this doesn't occur when I access it from groups contacts in Exchange Global Address List. As soon as I try to pick up the contact the application Crashes in iOS10 while in iOS9, it works just fine.

I have tried to debug both iOS 9 and 10 just to see the point that there is an issue as in iOS 10 the exception is on the compiled code. In iOS 9 there is a method which seems to be the first to be called when I choose a contact.

   // Called after a person has been selected by the user.
- (void)peoplePickerNavigationController:(ABPeoplePickerNavigationController*)peoplePicker didSelectPerson:(ABRecordRef)person
{
    CDVContactsPicker* picker = (CDVContactsPicker*)peoplePicker;
    NSNumber* pickedId = [NSNumber numberWithInt:ABRecordGetRecordID(person)];

    if (picker.allowsEditing) {
        ABPersonViewController* personController = [[ABPersonViewController alloc] init];
        personController.displayedPerson = person;
        personController.personViewDelegate = self;
        personController.allowsEditing = picker.allowsEditing;
        // store id so can get info in peoplePickerNavigationControllerDidCancel
        picker.pickedContactDictionary = [NSDictionary dictionaryWithObjectsAndKeys:pickedId, kW3ContactId, nil];

        [peoplePicker pushViewController:personController animated:YES];
    } else {
        // Retrieve and return pickedContact information
        CDVContact* pickedContact = [[CDVContact alloc] initFromABRecord:(ABRecordRef)person];
        NSArray* fields = [picker.options objectForKey:@"fields"];
        NSDictionary* returnFields = [[CDVContact class] calcReturnFields:fields];
        picker.pickedContactDictionary = [pickedContact toDictionary:returnFields];

        CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:picker.pickedContactDictionary];
        [self.commandDelegate sendPluginResult:result callbackId:picker.callbackId];

        [[picker presentingViewController] dismissViewControllerAnimated:YES completion:nil];
    }
}

However, in iOS10 it seems that application crashes before the call of that method. The exception I receive is:

2016-11-18 11:37:17.301332 myAppName[417:118946] *** Terminating app due to uncaught exception 'CNPropertyNotFetchedException', reason: 'A property was not requested when contact was fetched.'
*** First throw call stack:
(0x1859da1c0 0x18441455c 0x1859da108 0x18e159320 0x18e12a0e4 0x1858cdfb8 0x1858c4a64 0x18e12a030 0x18e129f1c 0x18e168f50 0x18fc16ce8 0x18fc43e6c 0x18f06b900 0x18f110f28 0x18f1116f4 0x1033c925c 0x1033c921c 0x1033ce284 0x185987f2c 0x185985b18 0x1858b4048 0x18733a198 0x18b8a02fc 0x18b89b034 0x1000e5e14 0x1848985b8)
libc++abi.dylib: terminating with uncaught exception of type NSException

In the debug console I typed bt and I received:

* thread #1: tid = 0x1d0a2, 0x00000001849aa014 libsystem_kernel.dylib`__pthread_kill + 8, queue = 'com.apple.main-thread', stop reason = signal SIGABRT
    frame #0: 0x00000001849aa014 libsystem_kernel.dylib`__pthread_kill + 8
    frame #1: 0x0000000184a72450 libsystem_pthread.dylib`pthread_kill + 112
    frame #2: 0x000000018491e3e0 libsystem_c.dylib`abort + 140
    frame #3: 0x00000001843e92d4 libc++abi.dylib`abort_message + 132
    frame #4: 0x0000000184406cc0 libc++abi.dylib`default_terminate_handler() + 304
    frame #5: 0x0000000184414844 libobjc.A.dylib`_objc_terminate() + 124
    frame #6: 0x000000018440366c libc++abi.dylib`std::__terminate(void (*)()) + 16
    frame #7: 0x0000000184402f84 libc++abi.dylib`__cxa_throw + 136
    frame #8: 0x0000000184414690 libobjc.A.dylib`objc_exception_throw + 364
    frame #9: 0x00000001859da108 CoreFoundation`+[NSException raise:format:] + 116
    frame #10: 0x000000018e159320 Contacts`-[CNContact sectionForSortingByFamilyName] + 164
    frame #11: 0x000000018e12a0e4 Contacts`__55-[CNContact(iOSABCompatibility) overwritePerson:error:]_block_invoke + 48
    frame #12: 0x00000001858cdfb8 CoreFoundation`__53-[__NSArrayI enumerateObjectsWithOptions:usingBlock:]_block_invoke + 100
    frame #13: 0x00000001858c4a64 CoreFoundation`-[__NSArrayI enumerateObjectsWithOptions:usingBlock:] + 188
    frame #14: 0x000000018e12a030 Contacts`-[CNContact(iOSABCompatibility) overwritePerson:error:] + 204
    frame #15: 0x000000018e129f1c Contacts`-[CNContact(iOSABCompatibility) detachedPersonWithError:] + 56
    frame #16: 0x000000018e168f50 Contacts`-[CNContactStore(iOSABCompatibility) personFromContact:] + 344
    frame #17: 0x000000018fc16ce8 AddressBookUI`-[CNContact(ABCompatibility) recordFromAddressBook:] + 80
    frame #18: 0x000000018fc43e6c AddressBookUI`-[ABPeoplePickerNavigationController contactPicker:didSelectContact:] + 152
    frame #19: 0x000000018f06b900 ContactsUI`-[CNContactPickerViewController pickerDidSelectContact:property:] + 296
    frame #20: 0x000000018f110f28 ContactsUI`-[CNContactPickerHostViewController pickerDidSelectContact:property:] + 100
    frame #21: 0x000000018f1116f4 ContactsUI`__71-[CNContactPickerExtensionHostContext pickerDidSelectContact:property:]_block_invoke + 60
    frame #22: 0x00000001033c925c libdispatch.dylib`_dispatch_call_block_and_release + 24
    frame #23: 0x00000001033c921c libdispatch.dylib`_dispatch_client_callout + 16
    frame #24: 0x00000001033ce284 libdispatch.dylib`_dispatch_main_queue_callback_4CF + 1200
    frame #25: 0x0000000185987f2c CoreFoundation`__CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 12
    frame #26: 0x0000000185985b18 CoreFoundation`__CFRunLoopRun + 1660
    frame #27: 0x00000001858b4048 CoreFoundation`CFRunLoopRunSpecific + 444
    frame #28: 0x000000018733a198 GraphicsServices`GSEventRunModal + 180
    frame #29: 0x000000018b8a02fc UIKit`-[UIApplication _run] + 684
    frame #30: 0x000000018b89b034 UIKit`UIApplicationMain + 208
  * frame #31: 0x00000001000e5e14 myAppName`main(argc=1, argv=0x000000016fd1f938) + 84 at main.m:34
    frame #32: 0x00000001848985b8 libdyld.dylib`start + 4

I attach also a picture that might help. The contacts work fine, but it crashes after choosing contact from exchange server. 崩溃的图像。在联系人中,一切正常。仅在交换服务器中。

Any help on that, it would be great.

Make sure NSContactsUsageDescription is in info.plist of your app.

Also the reason for the crash can be because iOS10 uses different class for person picker, so you need to have a check like below :

if (NSClassFromString(@"CNContactPickerViewController")) {
    // iOS 9, 10, use CNContactPickerViewController
    CNContactPickerViewController *picker = [[CNContactPickerViewController alloc] init];
    picker.delegate = self;
    picker.displayedPropertyKeys = @[CNContactPhoneNumbersKey];
    [pr presentViewController:picker animated:YES completion:nil];
}else{
    // iOS 8 Below, use ABPeoplePickerNavigationController
    ABPeoplePickerNavigationController *picker = [[ABPeoplePickerNavigationController alloc] init];
    picker.peoplePickerDelegate = self;
    [pr presentViewController:picker animated:YES completion:nil];
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM