使用Swift访问iOS通讯簿:数组计数为零

前端之家收集整理的这篇文章主要介绍了使用Swift访问iOS通讯簿:数组计数为零前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我试图写一个简单的方法,要求用户访问他们的通讯录,然后打印出通讯录中每个人的名字。我已经看到了一些教程解释如何在objective-C,但我有一个很难将它们转换为swift。

这是我到目前为止做的。下面的块运行在我的viewDidLoad()方法中,并检查用户是否已经授权访问通讯录,如果他们还没有授权访问,第一个if语句将要求访问。此部分按预期工作。

var emptyDictionary: CFDictionaryRef?

var addressBook: ABAddressBookRef?

        if (ABAddressBookGetAuthorizationStatus() == ABAuthorizationStatus.NotDetermined)
        {
            println("requesting access...")
            addressBook = !ABAddressBookCreateWithOptions(emptyDictionary,nil)
            ABAddressBookRequestAccessWithCompletion(addressBook,{success,error in
            if success {
                self.getContactNames();
            }
            else
            {
                println("error")
            }
        })
    }
        }
        else if (ABAddressBookGetAuthorizationStatus() == ABAuthorizationStatus.Denied || ABAddressBookGetAuthorizationStatus() == ABAuthorizationStatus.Restricted)
        {
            println("access denied")
        }
        else if (ABAddressBookGetAuthorizationStatus() == ABAuthorizationStatus.Authorized)
        {
            println("access granted")
            getContactNames()
        }

一旦我知道用户已授予访问权限,我运行getContactNames()方法如下。经过多次来回,我最终能够通过添加takeRetainedValue()方法来获得这个编译,以便将ABAddressBookCopyArrayOfAllPeople返回的数组从非托管数组转换为托管数组,然后允许我将CFArrayRef转换为NSArray。

我遇到的问题是,contactList数组的计数结果为0,因此for循环被跳过。在我的模拟器中,地址簿有6或7条记录,所以我希望数组具有这样的长度。有任何想法吗?

func getContactNames()
    {
        addressBook = !ABAddressBookCreateWithOptions(emptyDictionary,nil)
        var contactList: NSArray = ABAddressBookCopyArrayOfAllPeople(addressBook).takeRetainedValue()
        println("records in the array \(contactList.count)") // returns 0

        for record:ABRecordRef in contactList {
            var contactPerson: ABRecordRef = record
            var contactName: String = ABRecordCopyCompositeName(contactPerson).takeRetainedValue()
            println ("contactName \(contactName)")
        }
    }

另外一点 – 如果我使用ABAddressBookGetPersonCount方法,它返回-1。

var count: CFIndex = ABAddressBookGetPersonCount(addressBook);
        println("records in the array \(count)") // returns -1

基于这个链接ABAddressBookGetPersonCount returns -1 in iOS,似乎这个函数返回-1可能与权限未被授予相关,但我绝对已经在上面的代码请求权限(并在我在模拟器中运行应用程序时授予它)

这现在更简单了。要注意的主要事情是,如果你没有授权创建一个ABAddressBook,你会得到一个邪恶的地址簿 – 它不是零,但它也不是好的任何东西。以下是我目前建议您设置授权状态并在必要时请求授权的方法
var adbk : ABAddressBook!

func createAddressBook() -> Bool {
    if self.adbk != nil {
        return true
    }
    var err : Unmanaged<CFError>? = nil
    let adbk : ABAddressBook? = ABAddressBookCreateWithOptions(nil,&err).takeRetainedValue()
    if adbk == nil {
        println(err)
        self.adbk = nil
        return false
    }
    self.adbk = adbk
    return true
}

func determineStatus() -> Bool {
    let status = ABAddressBookGetAuthorizationStatus()
    switch status {
    case .Authorized:
        return self.createAddressBook()
    case .NotDetermined:
        var ok = false
        ABAddressBookRequestAccessWithCompletion(nil) {
            (granted:Bool,err:CFError!) in
            dispatch_async(dispatch_get_main_queue()) {
                if granted {
                    ok = self.createAddressBook()
                }
            }
        }
        if ok == true {
            return true
        }
        self.adbk = nil
        return false
    case .Restricted:
        self.adbk = nil
        return false
    case .Denied:
        self.adbk = nil
        return false
    }
}

下面是如何遍历所有人,并打印出他们的名字:

func getContactNames() {
    if !self.determineStatus() {
        println("not authorized")
        return
    }
    let people = ABAddressBookCopyArrayOfAllPeople(adbk).takeRetainedValue() as NSArray as [ABRecord]
    for person in people {
        println(ABRecordCopyCompositeName(person).takeRetainedValue())
    }
}

猜你在找的Swift相关文章