Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
AddressBook.swi, 
Alexsander*Akers*,*@a2
Address&Book&“Classes” 
ABAddressBookRef 
An#address#book. 
ABRecordRef 
A"person,"group,"or"source. 
ABMultiValueRef 
A"m...
Why$AB_____Ref? 
When%AddressBook.framework%debuted%in%Mac%OS%X% 
10.2%Jaguar,%it%featured%both%CBbased%Core% 
FoundaDon%a...
ABAddressBookRef 
An#address#book.
ABAddressBookRef+Crea.on 
Objec&ve(C 
extern ABAddressBookRef ABAddressBookCreateWithOptions( 
CFDictionaryRef options, 
C...
ABAddressBookRef+Crea.on 
var error: Unmanaged<CFErrorRef>? = nil 
var addressBook: ABAddressBookRef? = 
ABAddressBookCrea...
ABAddressBookRef+Authoriza2on 
let addressBook: ABAddressBookRef = /* ... */ 
ABAddressBookRequestAccessWithCompletion(add...
ABRecordRef 
A"person,"group,"or"source.
ABRecordRef 
Person
ABRecordRef 
Group
ABRecordRef 
Source
ABRecordRef*Acquisi/on 
let peoplePickerDelegate = /* some object */ 
let peoplePicker = ABPeoplePickerNavigationControlle...
ABRecordRef*Acquisi/on 
// In your ABPeoplePickerNavigationControllerDelegate 
func peoplePickerNavigationController( 
peo...
ABRecordRef*Acquisi/on 
let addressBook: ABAddressBookRef = /* ... */ 
// You can get a record's ID with ABRecordGetID() 
...
ABRecordRef*Values 
func ABRecordCopyValue( 
record: ABRecord!, 
property: ABPropertyID 
) -> Unmanaged<AnyObject>! 
let k...
ABRecordRef*Values 
let firstName: CFStringRef = ABRecordCopyValue( 
record, 
kABPersonFirstNameProperty 
)?.takeRetainedV...
ABRecordRef*Values 
let phones: ABMultiValueRef? = ABRecordCopyValue( 
record, 
kABPersonPhoneProperty 
)?.takeRetainedVal...
ABMul&ValueRef 
A"mul&'valued"property.
ABMul&ValueRef 
Almost'a'dic,onary?'! 
// Duplicate keys are bad. 
let phones: [String : String] = [ 
"Home": "+1 (718) 86...
ABMul&ValueRef 
An#array#of#tuples.#! 
let phones: [(String, String)] = [ 
("Home", "+1 (718) 861-4986"), 
("Work", "+1 (2...
ABMul&ValueRef 
let count: Int = ABMultiValueGetCount(phones) 
for i in 0..<count { 
let label: String = ABMultiValueCopyL...
ABMul&ValueRef 
Debugger'Output 
_$!<Home>!$_ -> +1 (718) 861-4986 
_$!<Work>!$_ -> +1 (212) 340-1938 
iPhone -> +1 (917) ...
_$!<WTF>!$_ 
_$!<Home>!$_ !!→!!!kABHomeLabel 
_$!<Work>!$_ !!→!!!kABWorkLabel 
_$!<Other>!$_!!→!!!kABOtherLabel 
These%are...
AddressBook.swi, 
Alexsander*Akers*,*@a2
Upcoming SlideShare
Loading in …5
×

AddressBook.swift

5,071 views

Published on

AddressBook.framework is definitely no one's favourite framework, especially with its outdated CoreFoundation-based API. This talk aims to show you how you can leverage AddressBook in your Swift apps whilst staying sane in the process.

Published in: Technology

AddressBook.swift

  1. 1. AddressBook.swi, Alexsander*Akers*,*@a2
  2. 2. Address&Book&“Classes” ABAddressBookRef An#address#book. ABRecordRef A"person,"group,"or"source. ABMultiValueRef A"mul&'valued"property.
  3. 3. Why$AB_____Ref? When%AddressBook.framework%debuted%in%Mac%OS%X% 10.2%Jaguar,%it%featured%both%CBbased%Core% FoundaDon%and%ObjecDveBC%APIs.%However,%when% the%iPhone%SDK%became%public%with%the%release%of% iPhone%OS%2.0,%its%AddressBook.framework%only% featured%the%CBbased%Core%FoundaDon%API. tl;dr C"based(Core(Founda.on(APIs(aren't(difficult(to(use,( per(se,(but(Swi<(makes(it(a(bit(harder.
  4. 4. ABAddressBookRef An#address#book.
  5. 5. ABAddressBookRef+Crea.on Objec&ve(C extern ABAddressBookRef ABAddressBookCreateWithOptions( CFDictionaryRef options, CFErrorRef *error ); Swi$ func ABAddressBookCreateWithOptions( options: CFDictionaryRef!, error: UnsafeMutablePointer<Unmanaged<CFErrorRef>?> ) -> Unmanaged<ABAddressBook>!
  6. 6. ABAddressBookRef+Crea.on var error: Unmanaged<CFErrorRef>? = nil var addressBook: ABAddressBookRef? = ABAddressBookCreateWithOptions(nil, &error)?.takeRetainedValue() if let addressBook = addressBook { // Success! } else { // Error let e = error!.takeUnretainedValue() as AnyObject as NSError println("An error occurred: (e)") }
  7. 7. ABAddressBookRef+Authoriza2on let addressBook: ABAddressBookRef = /* ... */ ABAddressBookRequestAccessWithCompletion(addressBook) { (success, error) in if success { // We can use the address book. } else { // User denied the request. let e = error as AnyObject as NSError println("An error occurred: (e)") } }
  8. 8. ABRecordRef A"person,"group,"or"source.
  9. 9. ABRecordRef Person
  10. 10. ABRecordRef Group
  11. 11. ABRecordRef Source
  12. 12. ABRecordRef*Acquisi/on let peoplePickerDelegate = /* some object */ let peoplePicker = ABPeoplePickerNavigationController() peoplePicker.delegate = peoplePickerDelegate viewController.presentViewController( peoplePicker, animated: true, completion: nil )
  13. 13. ABRecordRef*Acquisi/on // In your ABPeoplePickerNavigationControllerDelegate func peoplePickerNavigationController( peoplePicker: ABPeoplePickerNavigationController!, didSelectPerson person: ABRecord!) { // Do something with person } func peoplePickerNavigationControllerDidCancel( peoplePicker: ABPeoplePickerNavigationController!) { let p = peoplePicker.presentingViewController! p.dismissViewControllerAnimated(true, completion: nil) }
  14. 14. ABRecordRef*Acquisi/on let addressBook: ABAddressBookRef = /* ... */ // You can get a record's ID with ABRecordGetID() let recordID: ABRecordID = /* ... */ let unmanagedPerson: Unmanaged<ABRecordRef>? = ABAddressBookGetPersonWithRecordID(addressBook, recordID) // ABAddressBookGetGroupWithRecordID // ABAddressBookGetSourceWithRecordID if let person = unmanagedPerson?.takeUnretainedValue() { // You have a person! }
  15. 15. ABRecordRef*Values func ABRecordCopyValue( record: ABRecord!, property: ABPropertyID ) -> Unmanaged<AnyObject>! let kABPersonFirstNameProperty: ABPropertyID let kABPersonMiddleNameProperty: ABPropertyID let kABPersonLastNameProperty: ABPropertyID // etc.
  16. 16. ABRecordRef*Values let firstName: CFStringRef = ABRecordCopyValue( record, kABPersonFirstNameProperty )?.takeRetainedValue() if firstName != nil { let fn = firstName! as AnyObject as String println("The first name is (fn).") }
  17. 17. ABRecordRef*Values let phones: ABMultiValueRef? = ABRecordCopyValue( record, kABPersonPhoneProperty )?.takeRetainedValue() if let phones = phones { // We have an ABMultiValueRef. }
  18. 18. ABMul&ValueRef A"mul&'valued"property.
  19. 19. ABMul&ValueRef Almost'a'dic,onary?'! // Duplicate keys are bad. let phones: [String : String] = [ "Home": "+1 (718) 861-4986", "Work": "+1 (212) 340-1938", "iPhone": "+1 (917) 530-9127", "iPhone": "+1 (917) 251-8826" ] Keys%in%a%mul,-value%don't%have%to%be%unique.%A% person%could%have%two%mobile%numbers,%like%the%day% iPhone%/%night%iPhone%guy.
  20. 20. ABMul&ValueRef An#array#of#tuples.#! let phones: [(String, String)] = [ ("Home", "+1 (718) 861-4986"), ("Work", "+1 (212) 340-1938"), ("iPhone", "+1 (917) 530-9127"), ("iPhone", "+1 (917) 251-8826") ] This%representa,on%makes%more%sense%because%the% uniqueness%contstraint%is%gone.%The%tuple%consists%of%a% label%and%a%value.
  21. 21. ABMul&ValueRef let count: Int = ABMultiValueGetCount(phones) for i in 0..<count { let label: String = ABMultiValueCopyLabelAtIndex( phones, i )!.takeRetainedValue() as AnyObject as String let value: String = ABMultiValueCopyValueAtIndex( phones, i )!.takeRetainedValue() as AnyObject as String println("(label) -> (value)") }
  22. 22. ABMul&ValueRef Debugger'Output _$!<Home>!$_ -> +1 (718) 861-4986 _$!<Work>!$_ -> +1 (212) 340-1938 iPhone -> +1 (917) 530-9127 iPhone -> +1 (917) 251-8826
  23. 23. _$!<WTF>!$_ _$!<Home>!$_ !!→!!!kABHomeLabel _$!<Work>!$_ !!→!!!kABWorkLabel _$!<Other>!$_!!→!!!kABOtherLabel These%are%just%some%of%the%constants%used%by% AddressBook.framework%that%are%localized%in%Phone,% Contacts%and%ABPersonViewController%before% display%to%the%user.
  24. 24. AddressBook.swi, Alexsander*Akers*,*@a2

×