gpt4 book ai didi

ios - Swift访问iOS通讯录 : array count of zero

转载 作者:IT王子 更新时间:2023-10-29 05:00:24 27 4
gpt4 key购买 nike

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

这是我到目前为止所做的。下面的 block 在我的 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 转换为数组。

我遇到的问题是 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())
}
}

关于ios - Swift访问iOS通讯录 : array count of zero,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24752627/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com