Извлечение электронной почты из CNContactProperty - iOS 9

У меня есть приложение для iOS, которому нужен доступ к контроллеру представления выбора контактов, чтобы пользователь мог выбрать свойство контакта, такое как адрес электронной почты / номера телефонов адресов электронной почты imessage.

У меня сейчас проблема в том, что я не могу понять, как анализировать возвращаемые данные. Я использовал contactPicker didSelectContactProperty метод, но я не могу разобрать данные, которые мне нужны.

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

   CNLabeledValue *test = contactProperty.contact.emailAddresses.firstObject;
   NSLog(@"%@", test);

   NSLog(@"%@", contactProperty.contact.phoneNumbers);
}

Если вы запустите приведенный выше код, вы получите следующий ответ:

2015-10-11 13:30:07.059 Actions[516:212765] <CNLabeledValue: 0x13656d090: identifier=21F2B1B2-8158-466B-9224-E2036CA07D28, label=_$!<Other>!$_, value=News_Europe@iEUNS.com> 2015-10-11 13:30:07.061 App_Name[516:212765] (
    "<CNLabeledValue: 0x13672a500: identifier=6697A0E9-3B91-4566-B26E-83B87979F816, label=_$!<Main>!$_, value=<CNPhoneNumber: 0x13672a660: countryCode=gb, digits=08000391010>>" )

Это здорово, но как мне извлечь из него нужные мне данные? Почему операторы NSLog возвращают данные в странном формате?

Спасибо за ваше время, Дэн.

5 ответов

Решение

Возвращаемые значения принадлежат классу CNLabeledValue. Чтобы получить ценность от них, скажем, для электронных писем, сделайте это

CNLabeledValue *emailValue = contactProperty.contact.emailAddresses.firstObject;
NSString *emailString = email.value;

Если значение, которое вы хотели номер телефона, это, как вы могли бы получить это

CNLabeledValue *phoneNumberValue = contactProperty.contact.phoneNumbers.firstObject;
CNPhoneNumber *phoneNumber = phoneNumberValue.value;
NSString *phoneNumberString = phoneNumber.stringValue;

Потому что возвращаемое значение CNLabeledValue Вы также можете получить номер телефона или адрес электронной почты

NSString *emailLabel = emailValue.label; //This may be 'Work', 'Home', etc.
NSString *phoneNumberLabel = phoneNumberValue.label;

Быстрый

Это правильный способ, как это сделать:

      func contactPicker(_ picker: CNContactPickerViewController, didSelect contactProperty: CNContactProperty) {
    if contactProperty.key == CNContactEmailAddressesKey,
       let emailAddress = contactProperty.value as? String
    {
        print(emailAddress)
    }
}

Если бы вы выбралиcontactProperty.contact.emailAddresses.first, вы получите первый адрес электронной почты контакта, который может не обязательно быть адресом электронной почты, выбранным пользователем.

Если вы запрашиваете телефонные номера, используйте вместо этого следующее тело:

      if let phoneNumber = contactProperty.value as? CNPhoneNumber {
    print(phoneNumber.stringValue)
}

Для Swift 3.0:

 public func contactPicker(_ picker: CNContactPickerViewController, didSelect contact: CNContact)
{
      if let emailValue : CNLabeledValue = contact.emailAddresses.first
    {
        txtEmail.text = emailValue.value as String
    }
    if let phoneNumber : CNLabeledValue = contact.phoneNumbers.first
    {
        txtMobno.text = phoneNumber.value.stringValue
    }
     txtFname.text = contact.givenName + " " + contact.familyName

}

К сожалению, ответ Криса говорит вам, как получить значение из возвращаемого объекта CNLabeledValue, но он не говорит вам, как определить, какое CNLabeledValue было выбрано на основе параметра contactProperty, который имеет функция функции.

Что вам нужно сделать, так это перебрать каждый адрес электронной почты контакта и проверить, совпадает ли его идентификатор с выбранным идентификатором contactProperty. Используйте следующий код внутри функции didSelectContactProperty:

NSString *selectedEmail;

for (CNLabeledValue<NSString*>* email in contactProperty.contact.emailAddresses) {
    if ([email.identifier isEqualToString:contactProperty.identifier]) {
            selectedEmail = (NSString *)email.value;
    }
}

Примечание. Я тестировал этот код только с почтовыми адресами, поэтому может потребоваться дополнительная настройка для работы с адресами электронной почты.

Here is swift version of Chris answer :

 func fatchContacts(store : CNContactStore)  {
    do
    {
    let groups = try store.groups(matching: nil)
    let predicate =  CNContact.predicateForContactsInGroup(withIdentifier: groups[0].identifier)
    //let predicate = CNContact.predicateForContactsMatchingName("John")
        let keyToFatch = [CNContactFormatter.descriptorForRequiredKeys(for: .fullName ) ,CNContactEmailAddressesKey] as [Any]
    let contacts = try store.unifiedContacts(matching: predicate, keysToFetch: keyToFatch as! [CNKeyDescriptor])            //------------------------------------------------------
   //-------------Get Here-----------------------------------------
     print(contacts)
     print(contacts[0])
        let formatter = CNContactFormatter ()
        print(formatter.string(from: contacts[0]))
        print(contacts[0].givenName)
        print(contacts[0].emailAddresses)
        let emailValue : CNLabeledValue = contacts[0].emailAddresses.first!;
        let  email = emailValue.value
        print(email)




    }
    catch{

    }
}


Just pass the CNContactStore object        
Другие вопросы по тегам