如何通过swift访问用户联系人的电话号码?

时间:2015-07-24 15:20:54

标签: ios xcode swift contacts addressbook

以下是我获取联系人姓名的代码,我将如何获取他们的电话号码?

Location:([^\r?\n]+)

非常感谢任何帮助。

1 个答案:

答案 0 :(得分:4)

从iOS 9开始,我们将使用“联系人”框架,其中phoneNumbersCNLabeledValue<CNPhoneNumber>

let status = CNContactStore.authorizationStatus(for: .contacts)
if status == .denied || status == .restricted {
    presentSettingsAlert()
    return
}

// open it

let store = CNContactStore()
store.requestAccess(for: .contacts) { granted, error in
    guard granted else {
        self.presentSettingsAlert()
        return
    }

    // get the contacts

    let request = CNContactFetchRequest(keysToFetch: [CNContactFormatter.descriptorForRequiredKeys(for: .fullName), CNContactPhoneNumbersKey as CNKeyDescriptor])
    do {
        try store.enumerateContacts(with: request) { contact, stop in
            let name = CNContactFormatter.string(from: contact, style: .fullName)
            print(name)

            for phone in contact.phoneNumbers {
                var label = phone.label
                if label != nil {
                    label = CNLabeledValue<CNPhoneNumber>.localizedString(forLabel: label!)
                }
                print("  ", label, phone.value.stringValue)
            }
        }
    } catch {
        print(error)
    }
}

其中

private func presentSettingsAlert() {
    let settingsURL = URL(string: UIApplicationOpenSettingsURLString)!

    DispatchQueue.main.async {
        let alert = UIAlertController(title: "Permission to Contacts", message: "This app needs access to contacts in order to ...", preferredStyle: .alert)
        alert.addAction(UIAlertAction(title: "Go to Settings", style: .default) { _ in
            UIApplication.shared.openURL(settingsURL)
        })
        alert.addAction(UIAlertAction(title: "Cancel", style: .cancel))
        self.present(alert, animated: true)
    }
}

在iOS 9之前,您将使用联系人框架,其中电话号码为ABMultiValueRef,因此请获取该引用,然后遍历电话号码:

// make sure user hadn't previously denied access

let status = ABAddressBookGetAuthorizationStatus()
if status == .denied || status == .restricted {
    presentSettingsAlert()
    return
}

// open it

var error: Unmanaged<CFError>?
guard let addressBook: ABAddressBook? = ABAddressBookCreateWithOptions(nil, &error)?.takeRetainedValue() else {
    print(String(describing: error?.takeRetainedValue()))
    return
}

// request permission to use it

ABAddressBookRequestAccessWithCompletion(addressBook) { granted, error in
    if !granted {
        self.presentSettingsAlert()
        return
    }

    guard let people = ABAddressBookCopyArrayOfAllPeople(addressBook)?.takeRetainedValue() as [ABRecord]? else {
        print("unable to get contacts")
        return
    }

    for person in people {
        let name = ABRecordCopyCompositeName(person)?.takeRetainedValue() as String?
        print(name)

        if let phoneNumbers: ABMultiValue = ABRecordCopyValue(person, kABPersonPhoneProperty)?.takeRetainedValue() {
            for index in 0 ..< ABMultiValueGetCount(phoneNumbers) {
                let number = ABMultiValueCopyValueAtIndex(phoneNumbers, index)?.takeRetainedValue() as? String
                let label  = ABMultiValueCopyLabelAtIndex(phoneNumbers, index)?.takeRetainedValue()
                print("  ", self.localizedLabel(label), number)
            }
        }
    }
}

MacOS有一个本地化该标签的例程,但我不知道iOS的AddressBook框架中的任何此类公共函数,因此您可能希望自己转换它(或填充{{1}的本地化表}):

NSLocalizedString

对于Swift 2,请参阅previous revision of this answer