I am trying to write a simple method to ask a user to access their address book, and then print the name of each person in the address book. I saw several tutorials explaining how to do this in objective-C, but it's hard for me to convert them to swift.
Here is what I have done so far. The following block works in my viewDidLoad () method and checks if the user has authorized access to the address book or not, if they do not already have authorized access, the first if request requests access. This section works as expected.
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() }
As soon as I know that the user has granted access, I launched the getContactNames () method, which is below. After going back and forth a lot, I finally was able to get this to compile by adding the takeRetainedValue () method to convert the array returned by ABAddressBookCopyArrayOfAllPeople from an unmanaged array to a managed array, then this allows me to convert CFArrayRef to NSArray.
The problem I am facing is that the contactList array ends up having a number 0, and therefore the for loop is therefore skipped. In my sim, the address book has 6 or 7 entries, so I expect the array to be that long. Any ideas?
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)") } }
Another point - if I use the ABAddressBookGetPersonCount method, it returns -1.
var count: CFIndex = ABAddressBookGetPersonCount(addressBook); println("records in the array \(count)")
Based on this link, ABAddressBookGetPersonCount returns -1 in iOS , it looks like this function returning -1 could be related to granting permission, but I definitely asked for permission in the above code (and provided it when the application started in the simulator)