So I've just updated to Xcode 8 and converted my Swift 2.3 code to Swift 3, and I have an error in this line of code that wasn't in Swift 2.3:
func populateFrom(_ addressBook:ABAddressBook)
{
let allPeople = ABAddressBookCopyArrayOfAllPeople(addressBook).takeRetainedValue()
let nPeople = ABAddressBookGetPersonCount(addressBook)
for index in 0..<nPeople
{
let person:ABRecord = Unmanaged<ABRecord>.fromOpaque(OpaquePointer(CFArrayGetValueAtIndex(allPeople, index))).takeUnretainedValue()
}
}
Now the problem is in line let person:ABRecord = Unmanaged<ABRecord>.fromOpaque(OpaquePointer(CFArrayGetValueAtIndex(allPeople, index))).takeUnretainedValue()
Xcode tells me that 'fromOpaque' is unavailable: use 'fromOpaque(_:UnsafeRawPointer)' instead
. But I can't find that function Xcode is telling me to use, I can just find fromOpaque(value: UnsafeRawPointer)
which is the one I'm currently using.
How can I make this work?
You can simplify this a bit, eliminating all of those opaque pointer references, e.g.:
func populate(from addressBook: ABAddressBook) {
let allPeople = ABAddressBookCopyArrayOfAllPeople(addressBook).takeRetainedValue() as [ABRecord]
for person in allPeople {
let name = ABRecordCopyCompositeName(person).takeRetainedValue()
print(name)
}
}
Or, given that the AddressBook framework was deprecated in iOS 9, you can use the Contacts framework:
let store = CNContactStore()
store.requestAccess(for: .contacts) { granted, error in
guard granted else {
print(error)
return
}
self.populate(from: store)
}
And
func populate(from store: CNContactStore) {
let formatter = CNContactFormatter()
formatter.style = .fullName
let request = CNContactFetchRequest(keysToFetch: [CNContactFormatter.descriptorForRequiredKeys(for: formatter.style)])
do {
try store.enumerateContacts(with: request) { contact, stop in
print(formatter.string(from: contact))
}
} catch {
print(error)
}
}