我正在尝试编写一个简单的方法来要求用户访问他们的地址簿,然后打印出地址簿中每个人的姓名。我看过很多教程解释如何在 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 在 iOS 中返回 -1 https://stackoverflow.com/questions/13371996/abaddressbookgetpersoncount-returns-1-in-ios,似乎这个函数返回 -1 可能与未授予权限有关,但我确实在上面的代码中请求了权限(并在我在模拟器中运行应用程序时授予了权限)