如何使用Swift检索地址簿联系人? [英] How to retrieve address book contacts with Swift?

查看:183
本文介绍了如何使用Swift检索地址簿联系人?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我不明白为什么我的代码不能用Swift编译。

I don't understand why my code doesn't compile with Swift.

我试图转换这个Objective-C代码:

I am trying to convert this Objective-C code:

CFErrorRef error = NULL;
ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, &error);

  if (addressBook != nil) { 
    NSLog(@"Succesful."); 

    NSArray *allContacts = (__bridge_transfer NSArray *)ABAddressBookCopyArrayOfAllPeople(addressBook);
}

这是我目前在Swift中的表现:

This is my current rendition in Swift:

var error:CFErrorRef
var addressBook = ABAddressBookCreateWithOptions(nil, nil);

if (addressBook != nil) {
    println("Succesful.");

    var allContacts:CFArrayRef = ABAddressBookCopyArrayOfAllPeople(addressBook);
}

但是,Xcode报告:

but, Xcode reports:


'Unmanaged'不能转换为'CFArrayRef'

'Unmanaged' is not convertible to 'CFArrayRef'

你们有个主意吗? ?

推荐答案

显然,如果定位到iOS 9或更高版本,则不应使用 AddressBook 框架,而不是使用 Contacts 框架。

Obviously, if targeting iOS version 9 or greater, you shouldn't use the AddressBook framework at all, and instead use the Contacts framework instead.

所以, p>

So,


  1. 导入联系人

import Contacts


  • 确保在 Info.plist 中提供 NSContactsUsageDescription

    然后,您可以访问联系人。例如。在Swift 3中:

    Then, you can then access contacts. E.g. in Swift 3:

    let status = CNContactStore.authorizationStatus(for: .contacts)
    if status == .denied || status == .restricted {
        presentSettingsActionSheet()
        return
    }
    
    // open it
    
    let store = CNContactStore()
    store.requestAccess(for: .contacts) { granted, error in
        guard granted else {
            DispatchQueue.main.async {
                self.presentSettingsActionSheet()
            }
            return
        }
    
        // get the contacts
    
        var contacts = [CNContact]()
        let request = CNContactFetchRequest(keysToFetch: [CNContactIdentifierKey as NSString, CNContactFormatter.descriptorForRequiredKeys(for: .fullName)])
        do {
            try store.enumerateContacts(with: request) { contact, stop in
                contacts.append(contact)
            }
        } catch {
            print(error)
        }
    
        // do something with the contacts array (e.g. print the names)
    
        let formatter = CNContactFormatter()
        formatter.style = .fullName
        for contact in contacts {
            print(formatter.string(from: contact) ?? "???")
        }
    }
    

    其中

    func presentSettingsActionSheet() {
        let alert = UIAlertController(title: "Permission to Contacts", message: "This app needs access to contacts in order to ...", preferredStyle: .actionSheet)
        alert.addAction(UIAlertAction(title: "Go to Settings", style: .default) { _ in
            let url = URL(string: UIApplicationOpenSettingsURLString)!
            UIApplication.shared.open(url)
        })
        alert.addAction(UIAlertAction(title: "Cancel", style: .cancel))
        present(alert, animated: true)
    }
    


  • 我对AddressBook框架的原始答案如下。

    My original answer for AddressBook framework is below.

    一些观察结果:


    • 如果你想使用错误参数 ABAddressBookCreateWithOptions ,将其定义为 Unmanaged< CFError>?

    如果它失败了,看看错误对象(做 takeRetainedValue 所以你不要泄漏)。

    If it fails, take a look at the error object (doing takeRetainedValue so you don't leak).

    确保地址簿的 takeRetainedValue ,所以你不要泄密。

    Make sure to takeRetainedValue of the address book, too, so you don't leak.

    你可能不应该只是抓住联系人,但你可能应该首先请求许可。

    You probably shouldn't just grab the contacts, but you probably should request permission first.

    把所有这些都拉到一起你得到:

    Pulling that all together you get:

    // make sure user hadn't previously denied access
    
    let status = ABAddressBookGetAuthorizationStatus()
    if status == .Denied || status == .Restricted {
        // user previously denied, so tell them to fix that in settings
        return
    }
    
    // open it
    
    var error: Unmanaged<CFError>?
    guard let addressBook: ABAddressBook? = ABAddressBookCreateWithOptions(nil, &error)?.takeRetainedValue() else {
        print(error?.takeRetainedValue())
        return
    }
    
    // request permission to use it
    
    ABAddressBookRequestAccessWithCompletion(addressBook) { granted, error in
        if !granted {
            // warn the user that because they just denied permission, this functionality won't work
            // also let them know that they have to fix this in settings
            return
        }
    
        if let people = ABAddressBookCopyArrayOfAllPeople(addressBook)?.takeRetainedValue() as? NSArray {
            // now do something with the array of people
        }
    }
    

    这篇关于如何使用Swift检索地址簿联系人?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆