-
-
Save prrane/f2c0dde7158a02eed878 to your computer and use it in GitHub Desktop.
// based on : http://stackoverflow.com/questions/24752627/accessing-ios-address-book-with-swift-array-count-of-zero | |
// http://stackoverflow.com/questions/24752627/accessing-ios-address-book-with-swift-array-count-of-zero | |
class func extractABAddressBookRef(abRef: Unmanaged<ABAddressBookRef>!) -> ABAddressBookRef? { | |
if let ab = abRef { | |
return Unmanaged<NSObject>.fromOpaque(ab.toOpaque()).takeUnretainedValue() | |
} | |
return nil | |
} | |
class func testAddressBook() { | |
if (ABAddressBookGetAuthorizationStatus() == ABAuthorizationStatus.NotDetermined) { | |
println("requesting access...") | |
var errorRef: Unmanaged<CFError>? = nil | |
addressBook = extractABAddressBookRef(ABAddressBookCreateWithOptions(nil, &errorRef)) | |
ABAddressBookRequestAccessWithCompletion(addressBook, { success, error in | |
if success { | |
// prrane: add a call back some time later | |
// ABAddressBookRegisterExternalChangeCallback(addressBook, callback: (addressBook:ABAddressBookRef, info:CFDictionaryRef) -> , <#context: UnsafeMutablePointer<()>#>) | |
self.getContactNames() | |
} | |
else { | |
println("error") | |
} | |
}) | |
} | |
else if (ABAddressBookGetAuthorizationStatus() == ABAuthorizationStatus.Denied || ABAddressBookGetAuthorizationStatus() == ABAuthorizationStatus.Restricted) { | |
println("access denied") | |
} | |
else if (ABAddressBookGetAuthorizationStatus() == ABAuthorizationStatus.Authorized) { | |
println("access granted") | |
self.getContactNames() | |
} | |
} | |
class func getContactNames() { | |
var errorRef: Unmanaged<CFError>? | |
addressBook = extractABAddressBookRef(ABAddressBookCreateWithOptions(nil, &errorRef)) | |
var contactList: NSArray = ABAddressBookCopyArrayOfAllPeople(addressBook).takeRetainedValue() | |
println("records in the array \(contactList.count)") | |
for record:ABRecordRef in contactList { | |
if record != nil { | |
var contactPerson: ABRecordRef = record | |
println ("\n\n") | |
let emailProperty: ABMultiValueRef = ABRecordCopyValue(record, kABPersonEmailProperty).takeRetainedValue() as ABMultiValueRef | |
let allEmailIDs: NSArray = ABMultiValueCopyArrayOfAllValues(emailProperty).takeUnretainedValue() as NSArray | |
for email in allEmailIDs { | |
let emailID = email as String | |
println ("contactEmail : \(emailID) :=>") | |
} | |
if let contactNickname = ABRecordCopyValue(contactPerson, kABPersonNicknameProperty).takeRetainedValue() as? NSString { | |
println ("\t\t contactNickname : \(contactNickname)") | |
} | |
if let contactFirstName = ABRecordCopyValue(contactPerson, kABPersonFirstNameProperty).takeRetainedValue() as? NSString { | |
println ("\t\t contactFirstName : \(contactFirstName)") | |
} | |
if let contactLastName = ABRecordCopyValue(contactPerson, kABPersonLastNameProperty).takeRetainedValue() as? NSString { | |
println ("\t\t contactLastName : \(contactLastName)") | |
} | |
} | |
} | |
} |
Still fails if ABMultiValueRef is nil, user doesn't have emails in the case below.
let emails: ABMultiValueRef = ABRecordCopyValue(person,kABPersonEmailProperty).takeRetainedValue() as ABMultiValueRef
if ABMultiValueGetCount(emails) > 0 {
let allEmails = ABMultiValueCopyArrayOfAllValues(emails).takeRetainedValue() as NSArray
if allEmails.count > 0 {
for email in allEmails {
println(email)
}
}
}
l got a better ways to get emails and share it (in Swift 2.0*)
let emails: [String] = LCKPhoneContact.extractMultivalueProperty(record, propertyName: kABPersonEmailProperty)
class func extractProperty(recordRef: ABRecord, propertyName : ABPropertyID) -> T? {
//the following is two-lines of code for a reason. Do not combine (compiler optimization problems)
let value: AnyObject? = ABRecordCopyValue(recordRef, propertyName)?.takeRetainedValue()
return value as? T
}
class func extractMultivalueProperty(recordRef: ABRecord, propertyName : ABPropertyID) -> Array {
var array = Array()
let multivalue : ABMultiValue? = extractProperty(recordRef, propertyName: propertyName)
for i : Int in 0..<(ABMultiValueGetCount(multivalue)) {
let value : String? = ABMultiValueCopyValueAtIndex(multivalue, i).takeRetainedValue() as? String
if let value = value {
array.append(value)
}
}
if array.count > 0 {
return array
}
else {
return []
}
}
This is very helpful! I found that if the contact does not list an email you will get a crash on what is currently line 50.
So I added a check just before to make sure there are any emails.
Thanks.