我正在尝试使用swift获取具有特定名称的联系人列表。我有以下代码:
let owner = owners[indexPath.row];
var addressBook = ABAddressBookCreateWithOptions(nil, nil)
var addressBookRef: ABAddressBookRef = Unmanaged<NSObject>.fromOpaque(addressBook.toOpaque()).takeUnretainedValue()
let ownerName: NSString = owner["name"]! as NSString
let allContacts = ABAddressBookCopyPeopleWithName(addressBookRef, ownerName)
println("All Contacts: \(allContacts)")
显然,allContacts
的值为Swift.Unmanaged
。我希望allContacts
成为NSArray
。
在本教程中,通过将allContacts
添加到NSArray
,我跟随(__bridge NSArray*)
桥接到ABAddressBookCopyPeopleWithName(addressBookRef, ownerName)
。
可能导致此问题的原因是什么?
答案 0 :(得分:6)
您进行了大量包装/展开Unmanaged
和Opaque
类型的操作。你的行:
var addressBookRef: ABAddressBookRef = Unmanaged<NSObject>.fromOpaque(addressBook.toOpaque()).takeUnretainedValue()
相当于:
var addressBookRef = addressBook.takeUnretainedValue()
(此外,你应该使用let
,除非你想为该变量分配另一个值,这似乎不太可能。优化器会感谢你。)
在将参数传递给AddressBook API时,您不需要转换为基础类型,但是......但是我不能让ABAddressBookCopyPeopleWithName
在我的网格中返回非空数组测试,即使使用ObjC,也很难说。
如果你只是想打印数组,你只需要这个(使用ABAddressBookCopyArrayOfAllPeople
而不是因为上述问题,但返回数组的用法是相同的):
let addressBook: ABAddressBook =
ABAddressBookCreateWithOptions(nil, nil).takeRetainedValue()
let allContacts =
ABAddressBookCopyArrayOfAllPeople(addressBook).takeRetainedValue()
println("All Contacts: \(allContacts)")
(大概在获得addressBook
并使用它之间的某个时间你要么检查ABAddressBookGetAuthorizationStatus()
还是打电话给ABAddressBookRequestAccessWithCompletion
,对吗?)
如果您想使用数组中的ABRecord
值,则需要进行一些转换。 CoreFoundation类型桥接到Foundation类型,而Foundation数组桥接到Swift数组,但它并没有从CF到Swift的所有方式自动桥接。
for contact in ((allContacts as NSArray) as [ABRecord]) {
let name = ABRecordCopyCompositeName(contact).takeRetainedValue()
println(name)
}
(我在for
语句中添加括号以显示操作的层次结构,但您在代码中实际上并不需要它们。)