iOS 10 beta 上的联系人地址簿崩溃

Contact Address book crash on iOS 10 beta

当点击地址簿(在我的应用程序内)中的任何联系人时,它在 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 public 测试版时崩溃。

地址簿 API 在 iOS 9 中被弃用,取而代之的是更面向对象的 Contacts Framework

不使用 ABPeoplePickerViewController,移至 CNContactPickerViewController

将 "Privacy - Contacts Usage Description" 添加到您的 info.plist 。

Apple 论坛中也提出了同样的问题。 GWesley 的原始答案如下。

Apple Forum thread

尝试使用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;
}

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

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

有一个列表,其中包含您可以在 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) 数组中提供。