使用Swift访问iOS通讯簿:数组计数为零 [英] Accessing iOS Address Book with Swift: array count of zero

查看:120
本文介绍了使用Swift访问iOS通讯簿:数组计数为零的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试编写一种简单的方法,要求用户访问其地址簿,然后在地址簿中打印出每个人的姓名。我已经看过一些教程解释如何在Objective-C中执行此操作,但我很难将它们转换为swift。

I am trying to write a simple method to ask a user for access to their address book and then print out the name of each person in the address book. I've seen a number of tutorials explaining how to do this in objective-C, but am having a hard time converting them to swift.

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

Here's what I've done so far. The below block runs in my viewDidLoad() method and checks to see whether the user has authorized access to the address book or not, if they have not authorized access yet, the first if-statement will ask for access. This section works as expected.

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的。

Once I know the user has granted access, I run the getContactNames() method which is below. After much back and forth, I was finally able to get this to compile by adding the takeRetainedValue() method in order to convert the array returned by ABAddressBookCopyArrayOfAllPeople from an unmanaged array to a managed array, this then allows me to convert the CFArrayRef to an NSArray.

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

The issue I'm running into is that the contactList array ends up having a count of 0 and the for loop therefore gets skipped. In my simulator, the address book has 6 or 7 records, so I would expect the array to be of that length. Any ideas?

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。

One additional point - if I use the ABAddressBookGetPersonCount method, it returns -1.

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

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

Based on this link ABAddressBookGetPersonCount returns -1 in iOS, it seems that this function returning -1 could be related to permission not being granted, but I definitely have asked for permission in the code above (and granted it when I run the app in the simulator)

推荐答案

现在这简单得多了。需要注意的一件事是,如果你在没有授权的情况下创建一个ABAddressBook,你会得到一本邪恶的地址簿 - 它不是零,但它对任何东西都不好。以下是我目前建议您设置授权状态并在必要时请求授权的方式:

This is now all much simpler. The chief thing to watch out for is that if you create an ABAddressBook without authorization, you get an evil address book - it isn't nil but it isn't good for anything either. Here's how I currently recommend that you set up authorization status and request authorization if necessary:

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
    }
}

以下是如何循环所有人并打印出他们的名字:

And here's how to cycle through all persons and print out their names:

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访问iOS通讯簿:数组计数为零的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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