在iOS 10testing版中联系通讯簿崩溃

当点击地址簿中的任何联系人(在我的应用程序内)时,它将在iOS 10 beta版本中崩溃,并在iOS 9版本上正常运行;

这是崩溃日志

*** 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 

这里是我的应用程序中打开地址簿的代码:

 -(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); } } 

它仅在iOS 10公共testing版崩溃。

地址簿API在iOS 9中被弃用,以支持更多面向对象的联系人框架 。

而不是使用ABPeoplePickerViewController,移动到CNContactPickerViewController 。

尝试使用CNContactPickerViewController(iOS9及以上版本):

添加ContactsUI.framework,导入框架,声明委托CNContactPickerDelegate。

实现它(在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]; 

委托示例:

 - (void)contactPicker:(CNContactPickerViewController *)picker didSelectContactProperty:(CNContactProperty *)contactProperty{ CNPhoneNumber *phoneNumber = contactProperty.value; NSString *phoneStr = phoneNumber.stringValue; } 

将“隐私 – 联系人使用说明”添加到您的info.plist。

苹果论坛也提出了同样的问题。 下面给出GWesley的原始答案。

苹果论坛主题

iOS 10不允许访问联系人,直到我们提到为什么我们正在使用它。打开你的plist作为源代码在dict下面添加下面的代码现在再次运行它。

 <key>NSContactsUsageDescription</key> <string>$(PRODUCT_NAME) uses Contact</string> 

首先在info.plist添加NSContactsUsageDescription ,然后在AB请求访问块中呈现控制器。

 ABAddressBookRequestAccessWithCompletion(contactPicker, { success, error in if success { self.presentViewController(self.contactPicker, animated: true, completion: nil) } }) 

IOS 10现在需要用户权限来访问媒体库,照片,相机和其他硬件。 解决方法是将他们的密钥添加到info.plist中,并为用户描述我们如何使用他们的数据,iOS已经需要早些时候访问麦克风,相机和媒体库的权限(iOS6,iOS7),但是从iOS10开始,应用程序如果你不提供描述为什么你要求的权限会崩溃。

有一个可以在Info.plist文件中指定的所有cocoa密钥的列表

照片:

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

麦克风:

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

相机:

 Key : Privacy - Camera Usage Description Value : $(PRODUCT_NAME) camera use 

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) } 

代表例子

  @available(iOS 9.0, *) func contactPicker(_ picker: CNContactPickerViewController, didSelect contactProperty: CNContactProperty) { let emailAddress = contactProperty.value as? String } 

检查你是否提供了有效的密钥

 @[CNContactFamilyNameKey, CNContactGivenNameKey, CNContactPhoneNumbersKey, CNContactEmailAddressesKey] 

当他们从CNContact对象请求时。

例如:如果您需要调用contact.emailAddresses,则必须从(CNContactEmailAddressesKey)数组中提供。