I have a few functions for accessing the names and emails of people with ABAddressBook. The functions append the names and emails into a connections
array. The problem I'm facing is that when the user is asked for the first time to access their address book, and they tap yes, the array is loaded but the tableview isn't updated.
The second time the app is loaded (and they are not asked because they've already hit yes), the arrays are loaded AND the tableview is updated.
I can't figure out why this is the case. I don't think it has to do with reloadData()
because it does work on the second try.
My thought is that there is something incorrect about the logic of the code, but I can't figure it out.
Code:
func getAddressBookNames() {
let authorizationStatus = ABAddressBookGetAuthorizationStatus()
if (authorizationStatus == ABAuthorizationStatus.NotDetermined) {
var emptyDictionary: CFDictionaryRef?
var addressBook = !(ABAddressBookCreateWithOptions(emptyDictionary, nil) != nil)
ABAddressBookRequestAccessWithCompletion(addressBook,{success, error in
if success {
self.processContactNames();
}
else {
println("Unable to request access")
}
})
} else if (authorizationStatus == ABAuthorizationStatus.Denied || authorizationStatus == ABAuthorizationStatus.Restricted) {
println("access denied")
} else if (authorizationStatus == ABAuthorizationStatus.Authorized) {
println("access granted")
processContactNames()
}
}
func processContactNames()
{
var errorRef: Unmanaged<CFError>?
var addressBook: ABAddressBookRef? = extractABAddressBookRef(ABAddressBookCreateWithOptions(nil, &errorRef))
println(addressBook)
var contactList: NSArray = ABAddressBookCopyArrayOfAllPeople(addressBook).takeRetainedValue()
println("records in the array \(contactList.count)")
for record:ABRecordRef in contactList {
processAddressbookRecord(record)
}
}
func processAddressbookRecord(addressBookRecord: ABRecordRef) {
var contactName: String = ABRecordCopyCompositeName(addressBookRecord).takeRetainedValue() as NSString
connections.append("\(contactName) is an aquaintance")
connectionDetails.append("Learned from Contacts")
connectionCounter.text = "\(connections.count) Connections"
processEmail(addressBookRecord, contactNameForEmail: contactName)
}
func processEmail(addressBookRecord: ABRecordRef, contactNameForEmail: String) {
let emailArray:ABMultiValueRef = extractABEmailRef(ABRecordCopyValue(addressBookRecord, kABPersonEmailProperty))!
for (var j = 0; j < ABMultiValueGetCount(emailArray); ++j) {
var emailAdd = ABMultiValueCopyValueAtIndex(emailArray, j)
var emailString = extractABEmailAddress(emailAdd)
connections.append("\(contactNameForEmail)'s email is \(emailString!)")
connectionDetails.append("Learned from Contacts")
connectionCounter.text = "\(connections.count) Connections"
}
}
func extractABAddressBookRef(abRef: Unmanaged<ABAddressBookRef>!) -> ABAddressBookRef? {
if let ab = abRef {
return Unmanaged<NSObject>.fromOpaque(ab.toOpaque()).takeUnretainedValue()
}
return nil
}
func extractABEmailRef (abEmailRef: Unmanaged<ABMultiValueRef>!) -> ABMultiValueRef? {
if let ab = abEmailRef {
return Unmanaged<NSObject>.fromOpaque(ab.toOpaque()).takeUnretainedValue()
}
return nil
}
func extractABEmailAddress (abEmailAddress: Unmanaged<AnyObject>!) -> String? {
if let ab = abEmailAddress {
return Unmanaged.fromOpaque(abEmailAddress.toOpaque()).takeUnretainedValue() as CFStringRef
}
return nil
}