Ответ 1
API адресной книги устарел в iOS 9 в пользу более объектно-ориентированной Консолидация контактов.
Вместо использования ABPeoplePickerViewController перейдите в CNContactPickerViewController.
Когда вы нажимаете на какие-либо контакты в адресной книге (внутри моего приложения), он падает на бета-версию iOS 10 и отлично работает в версиях 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.
API адресной книги устарел в iOS 9 в пользу более объектно-ориентированной Консолидация контактов.
Вместо использования ABPeoplePickerViewController перейдите в CNContactPickerViewController.
Попробуйте использовать CNContactPickerViewController (iOS9 и выше):
Добавить ContactsUI.framework, импортировать фреймворк, объявить делегат CNContactPickerDelegate.
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;
}
Добавить "Privacy - Contacts Usage Description" в ваш info.plist.
Тот же вопрос был поднят на форумах Apple. Оригинальный ответ GWesley приведен ниже.
iOS 10 не разрешает доступ к контакту, пока мы не упомянем, почему мы его используем. Откройте ваш plist, поскольку исходный код добавьте ниже код в dict. Теперь запустите его снова.
<key>NSContactsUsageDescription</key>
<string>$(PRODUCT_NAME) uses Contact</string>
Сначала добавьте NSContactsUsageDescription
в info.plist
, а затем представите контроллер в блоке доступа запроса AB, например.
ABAddressBookRequestAccessWithCompletion(contactPicker, { success, error in
if success {
self.presentViewController(self.contactPicker, animated: true, completion: nil)
}
})
IOS 10 Теперь требуется разрешение пользователя на доступ к медиа-библиотеке, фотографиям, Камера и другое оборудование, подобное этим. Решением для этого является добавление их ключи в info.plist с описанием для пользователя, что мы используя свои данные, iOS уже потребовали разрешения на доступ микрофон, камеру и медиа-библиотеку ранее (iOS6, iOS7), но поскольку iOS10 приложения будут сбой, если вы не представите описание, почему вы запрашивают разрешение.
Список всех Cocoa ключей, которые можно указать в файле Info.plist
Фото:
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.
ex: если вам нужно вызвать contact.emailAddresses, он должен быть предоставлен из массива (CNContactEmailAddressesKey).