Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Contact Address book crash on iOS 10 beta

When click on any contacts in address book (inside my app) it's crashing on iOS 10 beta and working fine on iOS 9 versions;

This is the crash log

*** Terminating app due to uncaught exception 'CNPropertyNotFetchedException', reason: 'A property was not requested when contact was fetched.'
*** First throw call stack:
(0x1cf11a07 0x1c62af63 0x1cf1194d 0x246f0f4f 0x246c6a71 0x1ce355eb 0x1ce2e19b 0x246c69cf 0x246c6883 0x25e4a375 0x2538f283 0x254204ef 0x25420bb1 0xe9da97 0xe9da83 0xea2321 0x1cecf18f 0x1cecd477 0x1ce1e6bd 0x1ce1e549 0x1e54ebfd 0x21f961e3 0x21f90947 0x966c9 0x1ca9e507)
libc++abi.dylib: terminating with uncaught exception of type NSException

And here is the code to open address book inside my app:

-(void)showContactPicker {
__weak RecieverSelectorViewController *weakSelf = self;
    ABPeoplePickerNavigationController* picker = [[ABPeoplePickerNavigationController alloc] init];
    picker.peoplePickerDelegate = self;
    picker.modalPresentationStyle = UIModalPresentationFullScreen;
    picker.modalTransitionStyle = UIModalPresentationPopover;
    [self presentViewController:picker
                       animated:YES
                     completion:^{
                         [weakSelf hideLoadingAnimation];

                         // animation to show view controller has completed.
                     }];
}



- (void)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker didSelectPerson:(ABRecordRef)person property:(ABPropertyID)property identifier:(ABMultiValueIdentifier)identifier {
    [self setSelectedPerson:person];
}

- (void)peoplePickerNavigationController:(ABPeoplePickerNavigationController*)peoplePicker didSelectPerson:(ABRecordRef)person {
    [self setSelectedPerson:person];
}

-(void)setSelectedPerson:(ABRecordRef)person {


    NSString *contactName = CFBridgingRelease(ABRecordCopyCompositeName(person));

    ABMultiValueRef phoneRecord = ABRecordCopyValue(person, kABPersonPhoneProperty);
    CFStringRef phoneNumber = ABMultiValueCopyValueAtIndex(phoneRecord, 0);

    self.isSenderReciever = NO;

    NSString *phone = [PorterUtils
                       extraLast10DigitsFromDigitString:[PorterUtils
                                                         extractNumberFromText:(__bridge_transfer NSString *)phoneNumber]];




    //Handling Social Media Contacts - Crash

    if(contactName.length>0 && phone.length>0){

      [self setRecieverName:contactName
                   number:phone];
       CFRelease(phoneRecord);
    }

}

It's crashing only on iOS 10 public beta.

like image 941
Bangalore Avatar asked Jul 12 '16 10:07

Bangalore


7 Answers

Try to use CNContactPickerViewController (iOS9 and above):

Add ContactsUI.framework, import the framework, declare the delegate CNContactPickerDelegate.

Implement it (in Objective-C):

CNContactPickerViewController *peoplePicker = [[CNContactPickerViewController alloc] init];
    peoplePicker.delegate = self;
    NSArray *arrKeys = @[CNContactPhoneNumbersKey]; //display only phone numbers
    peoplePicker.displayedPropertyKeys = arrKeys;
    [self presentViewController:peoplePicker animated:YES completion:nil];

delegate example:

- (void)contactPicker:(CNContactPickerViewController *)picker didSelectContactProperty:(CNContactProperty *)contactProperty{ 

    CNPhoneNumber *phoneNumber = contactProperty.value;
    NSString *phoneStr = phoneNumber.stringValue;
}
like image 144
Elad Avatar answered Oct 05 '22 18:10

Elad


The Address Book API was deprecated in iOS 9 in favor of the more object-oriented Contacts Framework.

Instead of using the ABPeoplePickerViewController, move to CNContactPickerViewController.

like image 20
erdekhayser Avatar answered Oct 05 '22 19:10

erdekhayser


Add "Privacy - Contacts Usage Description" to your info.plist .

The same question was raised in Apple Forums. The original answer by GWesley is given below.

Apple Forum thread

like image 20
Amith Shaju Avatar answered Oct 05 '22 17:10

Amith Shaju


check whether you have provided valid keys like

@[CNContactFamilyNameKey, CNContactGivenNameKey, CNContactPhoneNumbersKey, CNContactEmailAddressesKey]

when they are requesting from CNContact object.

ex: if you need to call contact.emailAddresses it must be provided from (CNContactEmailAddressesKey) array.

like image 32
Subhash Avatar answered Oct 05 '22 17:10

Subhash


iOS 10 is not allowing to access the Contact until we mention Why we are using it.open your plist as Source code add the below code under dict Now run it again.

<key>NSContactsUsageDescription</key>
<string>$(PRODUCT_NAME) uses Contact</string>
like image 43
user3189586 Avatar answered Oct 05 '22 17:10

user3189586


IOS 10 Now Requires User Permission to Access Media Library, Photos, Camera and other Hardware like these. The solution for this is to add their keys into info.plist with description for user that how we are using their data , iOS already required permissions to access microphone, camera, and media library earlier (iOS6, iOS7), but since iOS10 the apps will crash if you don't provide the description why you are asking for the permission.

There is a list of all Cocoa Keys that you can specify in your Info.plist file

Photo :

Key       :  Privacy - Photo Library Usage Description    
Value   :  $(PRODUCT_NAME) photo use

Microphone :

Key        :  Privacy - Microphone Usage Description    
Value    :  $(PRODUCT_NAME) microphone use

Camera :

Key       :  Privacy - Camera Usage Description   
Value   :  $(PRODUCT_NAME) camera use
like image 42
user1374 Avatar answered Oct 05 '22 19:10

user1374


Swift 3

// This example allows the display and selection of email addresses only.
if #available(iOS 9.0, *) {
    let picker = CNContactPickerViewController()
    let arrKeys = [CNContactEmailAddressesKey] // array of properties to display
    picker.displayedPropertyKeys = arrKeys
    picker.delegate = self
    present(picker, animated: true, completion: nil)
}

Delegate example

    @available(iOS 9.0, *)
    func contactPicker(_ picker: CNContactPickerViewController, didSelect contactProperty: CNContactProperty) {
        let emailAddress = contactProperty.value as? String     
    }
like image 30
Luke Bartolomeo Avatar answered Oct 05 '22 17:10

Luke Bartolomeo