问题
Selecting a contact from contact picker crashes the app in iOS10.0. Contacts picker is shown using ABPeoplePickerNavigationController
like this:
let contactsPicker = ABPeoplePickerNavigationController()
contactsPicker.peoplePickerDelegate = self
self.presentViewController(contactsPicker, animated: true, completion: nil)
Here is the stack trace from crash log:
*** Terminating app due to uncaught exception 'CNPropertyNotFetchedException', reason: 'A property was not requested when contact was fetched.'
*** First throw call stack:
(
0 CoreFoundation 0x0000000105a1c34b __exceptionPreprocess + 171
1 libobjc.A.dylib 0x00000001052cd21e objc_exception_throw + 48
2 CoreFoundation 0x0000000105a85265 +[NSException raise:format:] + 197
3 Contacts 0x000000010dc6d96f -[CNContact sectionForSortingByFamilyName] + 160
4 Contacts 0x000000010dc3e18e __55-[CNContact(iOSABCompatibility) overwritePerson:error:]_block_invoke + 44
5 CoreFoundation 0x00000001059ad2fd __53-[__NSArrayI enumerateObjectsWithOptions:usingBlock:]_block_invoke + 77
6 CoreFoundation 0x00000001059ad1df -[__NSArrayI enumerateObjectsWithOptions:usingBlock:] + 207
7 Contacts 0x000000010dc3e0f4 -[CNContact(iOSABCompatibility) overwritePerson:error:] + 240
8 Contacts 0x000000010dc3dfc0 -[CNContact(iOSABCompatibility) detachedPersonWithError:] + 46
9 AddressBookUI 0x00000001057bdd77 -[ABPeoplePickerNavigationController contactPicker:didSelectContact:] + 145
10 ContactsUI 0x0000000112396eb2 -[CNContactPickerViewController pickerDidSelectContact:property:] + 306
11 ContactsUI 0x000000011243ee6f -[CNContactPickerHostViewController pickerDidSelectContact:property:] + 95
12 ContactsUI 0x000000011243f5ec __71-[CNContactPickerExtensionHostContext pickerDidSelectContact:property:]_block_invoke + 66
I have already added NSContactsUsageDescription
in the info.plist as discussed on Contact Address book crash on iOS 10 beta but that didn't help and I can't use CNContactPickerViewController
as I need to support iOS8 devices.
回答1:
Imran Raheem
From Erdekhayser's solution (Contact Address book crash on iOS 10 beta)
you can use this method to check CNContactPickerViewController is available?
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];
}
回答2:
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.
回答3:
I was getting the same error, when I was trying to get an emailAddresses
from CNContact
of delegate method.
Initially, I initialize the contactpicker:
//MARK: Contact Action
@IBAction func getContactListAction(_ sender: Any) {
let contactPicker = CNContactPickerViewController()
contactPicker.delegate = self
contactPicker.displayedPropertyKeys = [CNContactPhoneNumbersKey]
vcObject.present(contactPicker, animated: true, completion: nil)
}
Delegate method:
//MAKE: Contact Delegate
func contactPicker(_ picker: CNContactPickerViewController, didSelect contact: CNContact) {
picker.dismiss(animated: true, completion: nil)
let name = CNContactFormatter.string(from: contact, style: .fullName)
print(name!)
self.textfieldName.text = name!
for number in contact.phoneNumbers {
print("number ----\(number)")
let mobile = number.value.value(forKey: "digits") as? String
if (mobile?.count)! > 7 {
// your code goes here
print("mobile---\(String(describing: mobile))")
self.textfieldMobileNumber.text = mobile!
}
}
// this line couse the crash ---> print(contact.emailAddresses[0].value(forKey: "value") as! String)
}
I was accessing the email address without declaring in initialization.
Error -- Terminating app due to uncaught exception 'CNPropertyNotFetchedException', reason: 'A property was not requested when contact was fetched.'
CORRECT CODE FOR ACCESSING EMAIL ---
Xcode 10 . and 4.2
//MARK: Contact Action
@IBAction func getContactListAction(_ sender: Any) {
let contactPicker = CNContactPickerViewController()
contactPicker.delegate = self
contactPicker.displayedPropertyKeys = [CNContactPhoneNumbersKey,CNContactEmailAddressesKey] .
// <--- Here make declaration for accessing the required property from CNContact.
vcObject.present(contactPicker, animated: true, completion: nil)
}
//MAKE: Contact Delegate
func contactPicker(_ picker: CNContactPickerViewController, didSelect contact: CNContact) {
picker.dismiss(animated: true, completion: nil)
let name = CNContactFormatter.string(from: contact, style: .fullName)
print(name!)
self.textfieldName.text = name!
for number in contact.phoneNumbers {
print("number ----\(number)")
let mobile = number.value.value(forKey: "digits") as? String
if (mobile?.count)! > 7 {
// your code goes here
print("mobile---\(String(describing: mobile))")
self.textfieldMobileNumber.text = mobile!
}
}
// print(contact.emailAddresses[0].value.value(forKey: "labelValuePair") as! String)
for email in contact.emailAddresses {
print("number ----\(email)")
let eml = email.value(forKey: "value") as? String
print("eml --\(eml!)")
}
}
来源:https://stackoverflow.com/questions/39650873/address-book-crash-on-ios10