使用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())
    }
}

相关文章

软件简介:蓝湖辅助工具,减少移动端开发中控件属性的复制和粘...
现实生活中,我们听到的声音都是时间连续的,我们称为这种信...
前言最近在B站上看到一个漂亮的仙女姐姐跳舞视频,循环看了亿...
【Android App】实战项目之仿抖音的短视频分享App(附源码和...
前言这一篇博客应该是我花时间最多的一次了,从2022年1月底至...
因为我既对接过session、cookie,也对接过JWT,今年因为工作...