introducing the contacts framework · partial contacts let keystofetch = [cncontactgivennamekey,...

133
© 2015 Apple Inc. All rights reserved. Redistribution or public display not permitted without written permission from Apple. #WWDC15 Introducing the Contacts Framework For OS X, iOS, and watchOS Bruce Stadnyk iOS Contacts Engineer Dave Dribin OS X Contacts Engineer Julien Robert iOS Contacts Engineer App Frameworks Session 223

Upload: others

Post on 28-Sep-2020

1 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Introducing the Contacts Framework · Partial Contacts let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey] John givenName Appleseed familyName phoneNumbers john@example.com

© 2015 Apple Inc. All rights reserved. Redistribution or public display not permitted without written permission from Apple.

#WWDC15

Introducing the Contacts FrameworkFor OS X, iOS, and watchOS

Bruce Stadnyk iOS Contacts EngineerDave Dribin OS X Contacts EngineerJulien Robert iOS Contacts Engineer

App Frameworks

Session 223

Page 2: Introducing the Contacts Framework · Partial Contacts let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey] John givenName Appleseed familyName phoneNumbers john@example.com

What is Contacts Framework?

Page 3: Introducing the Contacts Framework · Partial Contacts let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey] John givenName Appleseed familyName phoneNumbers john@example.com

What is Contacts Framework?

Objective-C and Swift API

Page 4: Introducing the Contacts Framework · Partial Contacts let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey] John givenName Appleseed familyName phoneNumbers john@example.com

What is Contacts Framework?

Objective-C and Swift APIOptimized for thread-safe, read only usage

Page 5: Introducing the Contacts Framework · Partial Contacts let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey] John givenName Appleseed familyName phoneNumbers john@example.com

What is Contacts Framework?

Objective-C and Swift APIOptimized for thread-safe, read only usageOne API, multiple platforms

Page 6: Introducing the Contacts Framework · Partial Contacts let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey] John givenName Appleseed familyName phoneNumbers john@example.com

What is Contacts Framework?

Objective-C and Swift APIOptimized for thread-safe, read only usageOne API, multiple platformsAddressBook API being deprecated

Page 7: Introducing the Contacts Framework · Partial Contacts let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey] John givenName Appleseed familyName phoneNumbers john@example.com
Page 8: Introducing the Contacts Framework · Partial Contacts let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey] John givenName Appleseed familyName phoneNumbers john@example.com
Page 9: Introducing the Contacts Framework · Partial Contacts let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey] John givenName Appleseed familyName phoneNumbers john@example.com
Page 10: Introducing the Contacts Framework · Partial Contacts let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey] John givenName Appleseed familyName phoneNumbers john@example.com

What are Contacts?

Page 11: Introducing the Contacts Framework · Partial Contacts let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey] John givenName Appleseed familyName phoneNumbers john@example.com

What are Contacts?

Everyone has Contacts

Page 12: Introducing the Contacts Framework · Partial Contacts let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey] John givenName Appleseed familyName phoneNumbers john@example.com

What are Contacts?

Everyone has Contacts Phone, Mail, Messages, …

Page 13: Introducing the Contacts Framework · Partial Contacts let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey] John givenName Appleseed familyName phoneNumbers john@example.com

What are Contacts?

Everyone has Contacts Phone, Mail, Messages, …

Page 14: Introducing the Contacts Framework · Partial Contacts let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey] John givenName Appleseed familyName phoneNumbers john@example.com

What are Contacts?

Everyone has Contacts Phone, Mail, Messages, … Central to the user experience

Page 15: Introducing the Contacts Framework · Partial Contacts let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey] John givenName Appleseed familyName phoneNumbers john@example.com

Contact Properties

Page 16: Introducing the Contacts Framework · Partial Contacts let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey] John givenName Appleseed familyName phoneNumbers john@example.com

Contact Properties

John

Appleseed

[email protected] (home)

[email protected] (work)

(408) 555-0126 (iPhone)

Page 17: Introducing the Contacts Framework · Partial Contacts let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey] John givenName Appleseed familyName phoneNumbers john@example.com

Contact Properties

John

Appleseed

[email protected] (home)

[email protected] (work)

(408) 555-0126 (iPhone)

Page 18: Introducing the Contacts Framework · Partial Contacts let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey] John givenName Appleseed familyName phoneNumbers john@example.com

Contact Properties

John

Appleseed

[email protected] (home)

[email protected] (work)

(408) 555-0126 (iPhone)

Page 19: Introducing the Contacts Framework · Partial Contacts let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey] John givenName Appleseed familyName phoneNumbers john@example.com

Contact Properties

John

Appleseed

[email protected] (home)

[email protected] (work)

(408) 555-0126 (iPhone)

Page 20: Introducing the Contacts Framework · Partial Contacts let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey] John givenName Appleseed familyName phoneNumbers john@example.com

Contact Properties

John

Appleseed

[email protected] (home)

[email protected] (work)

(408) 555-0126 (iPhone)

Page 21: Introducing the Contacts Framework · Partial Contacts let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey] John givenName Appleseed familyName phoneNumbers john@example.com

Contact Properties

John

Appleseed

[email protected] (home)

[email protected] (work)

(408) 555-0126 (iPhone)

Page 22: Introducing the Contacts Framework · Partial Contacts let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey] John givenName Appleseed familyName phoneNumbers john@example.com

Contact Properties

John

Appleseed

[email protected] (home)

[email protected] (work)

(408) 555-0126 (iPhone)

Page 23: Introducing the Contacts Framework · Partial Contacts let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey] John givenName Appleseed familyName phoneNumbers john@example.com

Contact Properties

contact.imageData

contact.givenName

contact.familyName

contact.emailAddresses

contact.phoneNumbers

John

Appleseed

[email protected] (home)

[email protected] (work)

(408) 555-0126 (iPhone)

Page 24: Introducing the Contacts Framework · Partial Contacts let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey] John givenName Appleseed familyName phoneNumbers john@example.com

Contact Properties

contact.imageData

contact.givenName

contact.familyName

contact.emailAddresses

contact.phoneNumbers

John

Appleseed

[email protected] (home)

[email protected] (work)

(408) 555-0126 (iPhone)

Page 25: Introducing the Contacts Framework · Partial Contacts let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey] John givenName Appleseed familyName phoneNumbers john@example.com

Contact Properties

contact.imageData

contact.givenName

contact.familyName

contact.emailAddresses

contact.phoneNumbers

John

Appleseed

[email protected] (home)

[email protected] (work)

(408) 555-0126 (iPhone)

Page 26: Introducing the Contacts Framework · Partial Contacts let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey] John givenName Appleseed familyName phoneNumbers john@example.com

Contact Properties

contact.imageData

contact.givenName

contact.familyName

contact.emailAddresses

contact.phoneNumbers

John

Appleseed

[email protected] (home)

[email protected] (work)

(408) 555-0126 (iPhone)

Page 27: Introducing the Contacts Framework · Partial Contacts let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey] John givenName Appleseed familyName phoneNumbers john@example.com

Contact Properties

contact.imageData

contact.givenName

contact.familyName

contact.emailAddresses

contact.phoneNumbers

John

Appleseed

[email protected] (home)

[email protected] (work)

(408) 555-0126 (iPhone)

Page 28: Introducing the Contacts Framework · Partial Contacts let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey] John givenName Appleseed familyName phoneNumbers john@example.com

Contact Properties

contact.imageData

contact.givenName

contact.familyName

contact.emailAddresses

contact.phoneNumbers

John

Appleseed

[email protected] (home)

[email protected] (work)

(408) 555-0126 (iPhone)

Page 29: Introducing the Contacts Framework · Partial Contacts let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey] John givenName Appleseed familyName phoneNumbers john@example.com

Contact Objects

Page 30: Introducing the Contacts Framework · Partial Contacts let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey] John givenName Appleseed familyName phoneNumbers john@example.com

Contact Objects

CNContact

Page 31: Introducing the Contacts Framework · Partial Contacts let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey] John givenName Appleseed familyName phoneNumbers john@example.com

Contact Objects

CNContact

CNMutableContact

Page 32: Introducing the Contacts Framework · Partial Contacts let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey] John givenName Appleseed familyName phoneNumbers john@example.com

Contact Objects

CNContact

CNMutableContact

CNLabeledValue

Page 33: Introducing the Contacts Framework · Partial Contacts let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey] John givenName Appleseed familyName phoneNumbers john@example.com

Creating a New Contact

import Contacts

Page 34: Introducing the Contacts Framework · Partial Contacts let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey] John givenName Appleseed familyName phoneNumbers john@example.com

Creating a New Contact

import Contacts // create mutable for adding to the contact let contact = CNMutableContact()

Page 35: Introducing the Contacts Framework · Partial Contacts let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey] John givenName Appleseed familyName phoneNumbers john@example.com

Creating a New Contact

import Contacts // create mutable for adding to the contact let contact = CNMutableContact() contact.imageData = // profile picture as NSData

Page 36: Introducing the Contacts Framework · Partial Contacts let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey] John givenName Appleseed familyName phoneNumbers john@example.com

Creating a New Contact

import Contacts // create mutable for adding to the contact let contact = CNMutableContact() contact.imageData = // profile picture as NSData

Page 37: Introducing the Contacts Framework · Partial Contacts let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey] John givenName Appleseed familyName phoneNumbers john@example.com

Creating a New Contact

import Contacts // create mutable for adding to the contact let contact = CNMutableContact() contact.imageData = // profile picture as NSData contact.givenName = "John" contact.familyName = "Appleseed"

Page 38: Introducing the Contacts Framework · Partial Contacts let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey] John givenName Appleseed familyName phoneNumbers john@example.com

Creating a New ContactLabeled Values

let homeEmail = CNLabeledValue(label: CNLabelHome, value: "[email protected]") let workEmail = CNLabeledValue(label: CNLabelWork, value: "[email protected]")

Page 39: Introducing the Contacts Framework · Partial Contacts let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey] John givenName Appleseed familyName phoneNumbers john@example.com

Creating a New ContactLabeled Values

let homeEmail = CNLabeledValue(label: CNLabelHome, value: "[email protected]") let workEmail = CNLabeledValue(label: CNLabelWork, value: "[email protected]")

contact.emailAddresses = [homeEmail, workEmail]

Page 40: Introducing the Contacts Framework · Partial Contacts let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey] John givenName Appleseed familyName phoneNumbers john@example.com

Creating a New ContactLabeled Values

let homeEmail = CNLabeledValue(label: CNLabelHome, value: "[email protected]") let workEmail = CNLabeledValue(label: CNLabelWork, value: "[email protected]")

contact.emailAddresses = [homeEmail, workEmail]

contact.phoneNumbers = [CNLabeledValue( label: CNLabelPhoneNumberiPhone, value: CNPhoneNumber(stringValue: "(408) 555-0126"))]

Page 41: Introducing the Contacts Framework · Partial Contacts let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey] John givenName Appleseed familyName phoneNumbers john@example.com

Creating a New ContactLabeled Values

let address = CNMutablePostalAddress() address.street = "774 Loma Vista Ave" address.city = "Los Gatos" address.state = "CA" address.postalCode = "95032"

Page 42: Introducing the Contacts Framework · Partial Contacts let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey] John givenName Appleseed familyName phoneNumbers john@example.com

Creating a New ContactLabeled Values

let address = CNMutablePostalAddress() address.street = "774 Loma Vista Ave" address.city = "Los Gatos" address.state = "CA" address.postalCode = "95032"

contact.postalAddresses = [CNLabeledValue(label: CNLabelHome, value: address)]

Page 43: Introducing the Contacts Framework · Partial Contacts let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey] John givenName Appleseed familyName phoneNumbers john@example.com

Creating a New ContactDates

let birthday = NSDateComponents() birthday.day = 1 birthday.month = 4 birthday.year = 1988 // can omit for a year-less birthday

Page 44: Introducing the Contacts Framework · Partial Contacts let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey] John givenName Appleseed familyName phoneNumbers john@example.com

Creating a New ContactDates

let birthday = NSDateComponents() birthday.day = 1 birthday.month = 4 birthday.year = 1988 // can omit for a year-less birthday

contact.birthday = birthday

Page 45: Introducing the Contacts Framework · Partial Contacts let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey] John givenName Appleseed familyName phoneNumbers john@example.com

Formatting Contact Data

Page 46: Introducing the Contacts Framework · Partial Contacts let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey] John givenName Appleseed familyName phoneNumbers john@example.com

Formatting Contact Data

let fullName = CNContactFormatter.stringFromContact(contact, style: .FullName)

Page 47: Introducing the Contacts Framework · Partial Contacts let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey] John givenName Appleseed familyName phoneNumbers john@example.com

Formatting Contact Data

let fullName = CNContactFormatter.stringFromContact(contact, style: .FullName) print(fullName) // John Appleseed

Page 48: Introducing the Contacts Framework · Partial Contacts let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey] John givenName Appleseed familyName phoneNumbers john@example.com

Formatting Contact Data

let fullName = CNContactFormatter.stringFromContact(contact, style: .FullName) print(fullName) // John Appleseed

let postalString = CNPostalAddressFormatter.stringFromPostalAddress(address)

Page 49: Introducing the Contacts Framework · Partial Contacts let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey] John givenName Appleseed familyName phoneNumbers john@example.com

Formatting Contact Data

let fullName = CNContactFormatter.stringFromContact(contact, style: .FullName) print(fullName) // John Appleseed

let postalString = CNPostalAddressFormatter.stringFromPostalAddress(address) print(postalString) // 774 Loma Vista Ave // Los Gatos, CA 95032

Page 50: Introducing the Contacts Framework · Partial Contacts let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey] John givenName Appleseed familyName phoneNumbers john@example.com

Using Contacts in Your App

Dave Dribin OS X Contacts Engineer

Page 51: Introducing the Contacts Framework · Partial Contacts let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey] John givenName Appleseed familyName phoneNumbers john@example.com
Page 52: Introducing the Contacts Framework · Partial Contacts let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey] John givenName Appleseed familyName phoneNumbers john@example.com
Page 53: Introducing the Contacts Framework · Partial Contacts let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey] John givenName Appleseed familyName phoneNumbers john@example.com

Using Contacts in Your App

CNContactStore

Page 54: Introducing the Contacts Framework · Partial Contacts let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey] John givenName Appleseed familyName phoneNumbers john@example.com

Fetching User's Contacts

class CNContactStore : NSObject {

func unifiedContactsMatchingPredicate(

predicate: NSPredicate,

keysToFetch: [CNKeyDescriptor]) -> [CNContact] throws

...

}

Page 55: Introducing the Contacts Framework · Partial Contacts let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey] John givenName Appleseed familyName phoneNumbers john@example.com

Predicateslet predicate = CNContact.predicateForContactsMatchingName("Appleseed")

Page 56: Introducing the Contacts Framework · Partial Contacts let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey] John givenName Appleseed familyName phoneNumbers john@example.com

Predicateslet predicate = CNContact.predicateForContactsMatchingName("Appleseed")

John

Appleseed

[email protected] (home)[email protected] (work)

(408) 555-0126 (iPhone)

April 1, 1988 (birthday)

Jane

Appleseed

[email protected] (home)

(505) 555-0155 (home)(408) 555-0166 (work)

Craig

Bromley

[email protected] (work)

(465) 555-0199 (iPhone)

Jun 21 (birthday)

Page 57: Introducing the Contacts Framework · Partial Contacts let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey] John givenName Appleseed familyName phoneNumbers john@example.com

Predicateslet predicate = CNContact.predicateForContactsMatchingName("Appleseed")

John

Appleseed

[email protected] (home)[email protected] (work)

(408) 555-0126 (iPhone)

April 1, 1988 (birthday)

Jane

Appleseed

[email protected] (home)

(505) 555-0155 (home)(408) 555-0166 (work)

Craig

Bromley

[email protected] (work)

(465) 555-0199 (iPhone)

Jun 21 (birthday)

Page 58: Introducing the Contacts Framework · Partial Contacts let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey] John givenName Appleseed familyName phoneNumbers john@example.com

Keys to Fetchlet keysToFetch = ["givenName", "familyName"]

imageData

givenName

familyName

emailAddresses

phoneNumbers

birthday

Jane

Appleseed

[email protected] (home)

(505) 555-0155 (home)(408) 555-0166 (work)

John

Appleseed

[email protected] (home)[email protected] (work)

(408) 555-0126 (iPhone)

April 1, 1988 (birthday)

Page 59: Introducing the Contacts Framework · Partial Contacts let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey] John givenName Appleseed familyName phoneNumbers john@example.com

Keys to Fetchlet keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey]

imageData

givenName

familyName

emailAddresses

phoneNumbers

birthday

John

Appleseed

[email protected] (home)[email protected] (work)

(408) 555-0126 (iPhone)

April 1, 1988 (birthday)

Jane

Appleseed

[email protected] (home)

(505) 555-0155 (home)(408) 555-0166 (work)

Page 60: Introducing the Contacts Framework · Partial Contacts let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey] John givenName Appleseed familyName phoneNumbers john@example.com

Keys to Fetchlet keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey]

imageData

givenName

familyName

emailAddresses

phoneNumbers

birthday

John

Appleseed

[email protected] (home)[email protected] (work)

(408) 555-0126 (iPhone)

April 1, 1988 (birthday)

Jane

Appleseed

[email protected] (home)

(505) 555-0155 (home)(408) 555-0166 (work)

Page 61: Introducing the Contacts Framework · Partial Contacts let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey] John givenName Appleseed familyName phoneNumbers john@example.com

How to Fetch

let predicate = CNContact.predicateForContactsMatchingName("Appleseed") let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey]

Page 62: Introducing the Contacts Framework · Partial Contacts let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey] John givenName Appleseed familyName phoneNumbers john@example.com

How to Fetch

let predicate = CNContact.predicateForContactsMatchingName("Appleseed") let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey]

let store = CNContactStore() let contacts = try store.unifiedContactsMatchingPredicate(predicate, keysToFetch: keysToFetch)

Page 63: Introducing the Contacts Framework · Partial Contacts let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey] John givenName Appleseed familyName phoneNumbers john@example.com

How to Fetch

let predicate = CNContact.predicateForContactsMatchingName("Appleseed") let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey]

let store = CNContactStore() let contacts = try store.unifiedContactsMatchingPredicate(predicate, keysToFetch: keysToFetch)

for contact in contacts { print("\(contact.givenName) \(contact.familyName)") }

Page 64: Introducing the Contacts Framework · Partial Contacts let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey] John givenName Appleseed familyName phoneNumbers john@example.com

Keeping UI ResponsiveMain Queue Background Queue

Fetch Contacts

CNContactCNContactCNContact

Page 65: Introducing the Contacts Framework · Partial Contacts let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey] John givenName Appleseed familyName phoneNumbers john@example.com

Keeping UI ResponsiveMain Queue Background Queue

Fetch Contacts

CNContactCNContactCNContact

CNContactCNContactCNContact

Page 66: Introducing the Contacts Framework · Partial Contacts let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey] John givenName Appleseed familyName phoneNumbers john@example.com

Data Privacy

Page 67: Introducing the Contacts Framework · Partial Contacts let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey] John givenName Appleseed familyName phoneNumbers john@example.com

Data Privacyclass CNContactStore : NSObject { func requestAccessForEntityType(..., completionHandler:) }

Privacy and Your App Pacific Heights Tuesday 2:30PM

Page 68: Introducing the Contacts Framework · Partial Contacts let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey] John givenName Appleseed familyName phoneNumbers john@example.com

Partial Contactslet keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey]

John

Appleseed

[email protected] (home)[email protected] (work)

(408) 555-0126 (iPhone)

April 1, 1988 (birthday)

John givenName

Appleseed familyName

[email protected] (home)[email protected] (work)

(408) 555-0126 (iPhone)

April 1, 1988 (birthday)

Page 69: Introducing the Contacts Framework · Partial Contacts let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey] John givenName Appleseed familyName phoneNumbers john@example.com

Partial Contactslet keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey]

John givenName

Appleseed familyName

phoneNumbers

[email protected] (home)[email protected] (work)

(408) 555-0126 (iPhone)

April 1, 1988 (birthday)

John

Appleseed

[email protected] (home)[email protected] (work)

(408) 555-0126 (iPhone)

April 1, 1988 (birthday)

Page 70: Introducing the Contacts Framework · Partial Contacts let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey] John givenName Appleseed familyName phoneNumbers john@example.com

Partial Contacts

if (contact.isKeyAvailable(CNContactPhoneNumbersKey)) { print("\(contact.phoneNumbers)") }

Page 71: Introducing the Contacts Framework · Partial Contacts let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey] John givenName Appleseed familyName phoneNumbers john@example.com

Partial Contacts

if (contact.isKeyAvailable(CNContactPhoneNumbersKey)) { print("\(contact.phoneNumbers)") } else { let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey, CNContactPhoneNumbersKey] var refetchedContact = try store.unifiedContactWithIdentifier( contact.identifier, keysToFetch: keysToFetch) print("\(refetchedContact.phoneNumbers)") }

Page 72: Introducing the Contacts Framework · Partial Contacts let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey] John givenName Appleseed familyName phoneNumbers john@example.com

Mr. namePrefix

John givenName

middleName

Appleseed familyName

Sr. nameSuffix

Formatting Partial Contactslet keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey]

Page 73: Introducing the Contacts Framework · Partial Contacts let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey] John givenName Appleseed familyName phoneNumbers john@example.com

Mr. namePrefix

John givenName

middleName

Appleseed familyName

Sr. nameSuffix

Formatting Partial Contactslet keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey,

CNContactNamePrefixKey, CNContactMiddleNameKey, ...]

Page 74: Introducing the Contacts Framework · Partial Contacts let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey] John givenName Appleseed familyName phoneNumbers john@example.com

Formatting Partial Contacts

Mr. namePrefix

John givenName

middleName

Appleseed familyName

Sr. nameSuffix

+ Any Others

let keysToFetch =

[CNContactFormatter.descriptorForRequiredKeysForStyle(.FullName)]

Page 75: Introducing the Contacts Framework · Partial Contacts let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey] John givenName Appleseed familyName phoneNumbers john@example.com

Key Descriptors

let predicate = CNContact.predicateForContactsMatchingName("Appleseed") let keysToFetch = [ CNContactFormatter.descriptorForRequiredKeysForStyle(.FullName), CNContactEmailAddressesKey]

Page 76: Introducing the Contacts Framework · Partial Contacts let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey] John givenName Appleseed familyName phoneNumbers john@example.com

Key Descriptors

let predicate = CNContact.predicateForContactsMatchingName("Appleseed") let keysToFetch = [ CNContactFormatter.descriptorForRequiredKeysForStyle(.FullName), CNContactEmailAddressesKey]

let contacts = try store.unifiedContactsMatchingPredicate(predicate, keysToFetch: keysToFetch)

Page 77: Introducing the Contacts Framework · Partial Contacts let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey] John givenName Appleseed familyName phoneNumbers john@example.com

Key Descriptors

let predicate = CNContact.predicateForContactsMatchingName("Appleseed") let keysToFetch = [ CNContactFormatter.descriptorForRequiredKeysForStyle(.FullName), CNContactEmailAddressesKey]

let contacts = try store.unifiedContactsMatchingPredicate(predicate, keysToFetch: keysToFetch)

for contact in contacts { let fullName = CNContactFormatter.stringFromContact( contact, style: .FullName) ?? "No Name" print("\(fullName): \(contact.emailAddresses)") }

Page 78: Introducing the Contacts Framework · Partial Contacts let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey] John givenName Appleseed familyName phoneNumbers john@example.com

Unified Contacts

John

Appleseed

[email protected] (work)

(408) 555-0126 (iPhone)

iCloud

John

Appleseed

[email protected] (home)

April 1, 1988 (birthday)

Facebook

Page 79: Introducing the Contacts Framework · Partial Contacts let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey] John givenName Appleseed familyName phoneNumbers john@example.com

John

Appleseed

[email protected] (work) [email protected] (home)

(408) 555-0126 (iPhone)

April 1, 1988 (birthday)

Unified

Unified Contacts

John

Appleseed

[email protected] (work)

(408) 555-0126 (iPhone)

iCloud

John

Appleseed

[email protected] (home)

April 1, 1988 (birthday)

Facebook

Page 80: Introducing the Contacts Framework · Partial Contacts let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey] John givenName Appleseed familyName phoneNumbers john@example.com

Adding a New Contact

let john = CNMutableContact() john.givenName = "John" john.familyName = "Appleseed"

Page 81: Introducing the Contacts Framework · Partial Contacts let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey] John givenName Appleseed familyName phoneNumbers john@example.com

let john = CNMutableContact() john.givenName = "John" john.familyName = "Appleseed"

let saveRequest = CNSaveRequest() saveRequest.addContact(john, toContainerWithIdentifier: nil) try store.executeSaveRequest(saveRequest)

Adding a New Contact

Page 82: Introducing the Contacts Framework · Partial Contacts let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey] John givenName Appleseed familyName phoneNumbers john@example.com

Updating an Existing Contact

let updatedContact = contact.mutableCopy() let newEmail = CNLabeledValue(label: CNLabelHome, value: "[email protected]") updatedContact.emailAddresses.append(newEmail)

Page 83: Introducing the Contacts Framework · Partial Contacts let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey] John givenName Appleseed familyName phoneNumbers john@example.com

Updating an Existing Contact

let updatedContact = contact.mutableCopy() let newEmail = CNLabeledValue(label: CNLabelHome, value: "[email protected]") updatedContact.emailAddresses.append(newEmail)

let saveRequest = CNSaveRequest() saveRequest.updateContact(updatedContact) try store.executeSaveRequest(saveRequest)

Page 84: Introducing the Contacts Framework · Partial Contacts let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey] John givenName Appleseed familyName phoneNumbers john@example.com

Contacts in the UI

Julien Robert iOS Contacts Engineer

Page 85: Introducing the Contacts Framework · Partial Contacts let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey] John givenName Appleseed familyName phoneNumbers john@example.com

ContactsUINew framework

Page 86: Introducing the Contacts Framework · Partial Contacts let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey] John givenName Appleseed familyName phoneNumbers john@example.com

ContactsUINew framework

iOS OS X

Page 87: Introducing the Contacts Framework · Partial Contacts let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey] John givenName Appleseed familyName phoneNumbers john@example.com

ContactsUINew framework

iOS OS X

CNContactPickerViewController CNContactPicker

Page 88: Introducing the Contacts Framework · Partial Contacts let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey] John givenName Appleseed familyName phoneNumbers john@example.com

ContactsUINew framework

iOS OS X

CNContactPickerViewController CNContactPicker

CNContactViewController CNContactViewController

Page 89: Introducing the Contacts Framework · Partial Contacts let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey] John givenName Appleseed familyName phoneNumbers john@example.com

Picking ContactsCNContactPickerViewController

Page 90: Introducing the Contacts Framework · Partial Contacts let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey] John givenName Appleseed familyName phoneNumbers john@example.com

Picking ContactsCNContactPickerViewController

Modern replacement for ABPeoplePickerNavigationController

Page 91: Introducing the Contacts Framework · Partial Contacts let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey] John givenName Appleseed familyName phoneNumbers john@example.com

Picking ContactsCNContactPickerViewController

Modern replacement for ABPeoplePickerNavigationControllerMust be presented, not pushed

Page 92: Introducing the Contacts Framework · Partial Contacts let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey] John givenName Appleseed familyName phoneNumbers john@example.com

Picking ContactsCNContactPickerViewController

Modern replacement for ABPeoplePickerNavigationControllerMust be presented, not pushedAlways out of process, no contacts access dialog

Page 93: Introducing the Contacts Framework · Partial Contacts let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey] John givenName Appleseed familyName phoneNumbers john@example.com

Picking ContactsCNContactPickerViewController

Modern replacement for ABPeoplePickerNavigationControllerMust be presented, not pushedAlways out of process, no contacts access dialogMay return partial contacts

Page 94: Introducing the Contacts Framework · Partial Contacts let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey] John givenName Appleseed familyName phoneNumbers john@example.com

Picking ContactsCNContactPickerViewController

Modern replacement for ABPeoplePickerNavigationControllerMust be presented, not pushedAlways out of process, no contacts access dialogMay return partial contactsBehavior based on delegate methods and predicates

Page 95: Introducing the Contacts Framework · Partial Contacts let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey] John givenName Appleseed familyName phoneNumbers john@example.com

Picking ContactsCNContactPickerViewController

Modern replacement for ABPeoplePickerNavigationControllerMust be presented, not pushedAlways out of process, no contacts access dialogMay return partial contactsBehavior based on delegate methods and predicatesSupports multi-selection

Page 96: Introducing the Contacts Framework · Partial Contacts let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey] John givenName Appleseed familyName phoneNumbers john@example.com

Picking ContactsDelegate methods

Page 97: Introducing the Contacts Framework · Partial Contacts let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey] John givenName Appleseed familyName phoneNumbers john@example.com

Picking ContactsDelegate methods

Single contact

Page 98: Introducing the Contacts Framework · Partial Contacts let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey] John givenName Appleseed familyName phoneNumbers john@example.com

Picking ContactsDelegate methods

Single contact contactPicker(picker, didSelectContact contact: CNContact)

Page 99: Introducing the Contacts Framework · Partial Contacts let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey] John givenName Appleseed familyName phoneNumbers john@example.com

Picking ContactsDelegate methods

Single contact contactPicker(picker, didSelectContact contact: CNContact)

Single propertycontactPicker(picker, didSelectContactProperty property: CNContactProperty)

Page 100: Introducing the Contacts Framework · Partial Contacts let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey] John givenName Appleseed familyName phoneNumbers john@example.com

Picking ContactsDelegate methods

Single contact contactPicker(picker, didSelectContact contact: CNContact)

Single propertycontactPicker(picker, didSelectContactProperty property: CNContactProperty)

class CNContactProperty { var contact: CNContact var key: NSString var value: AnyObject? var identifier: NSString? }

Page 101: Introducing the Contacts Framework · Partial Contacts let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey] John givenName Appleseed familyName phoneNumbers john@example.com

Picking ContactsDelegate methods

Page 102: Introducing the Contacts Framework · Partial Contacts let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey] John givenName Appleseed familyName phoneNumbers john@example.com

Picking ContactsDelegate methods

Multiple contacts

Page 103: Introducing the Contacts Framework · Partial Contacts let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey] John givenName Appleseed familyName phoneNumbers john@example.com

Picking ContactsDelegate methods

Multiple contactscontactPicker(picker, didSelectContacts contacts: [CNContact])

Page 104: Introducing the Contacts Framework · Partial Contacts let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey] John givenName Appleseed familyName phoneNumbers john@example.com

Picking ContactsDelegate methods

Multiple contactscontactPicker(picker, didSelectContacts contacts: [CNContact])

Multiple propertiescontactPicker(picker, didSelectContactProperties properties: [CNContactProperty])

Page 105: Introducing the Contacts Framework · Partial Contacts let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey] John givenName Appleseed familyName phoneNumbers john@example.com

Picking ContactsPredicates

Page 106: Introducing the Contacts Framework · Partial Contacts let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey] John givenName Appleseed familyName phoneNumbers john@example.com

Picking ContactsPredicates

predicateForEnablingContact

• Which contacts are available• Evaluated on CNContact

Page 107: Introducing the Contacts Framework · Partial Contacts let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey] John givenName Appleseed familyName phoneNumbers john@example.com

Picking ContactsPredicates

predicateForEnablingContact

• Which contacts are available• Evaluated on CNContact

Page 108: Introducing the Contacts Framework · Partial Contacts let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey] John givenName Appleseed familyName phoneNumbers john@example.com

Picking ContactsPredicates

predicateForEnablingContact

• Which contacts are available• Evaluated on CNContact

let predicate = NSPredicate(format: "familyName LIKE[cd] 'parker'")

Page 109: Introducing the Contacts Framework · Partial Contacts let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey] John givenName Appleseed familyName phoneNumbers john@example.com

Picking ContactsPredicates

predicateForEnablingContact

• Which contacts are available• Evaluated on CNContact

let predicate = NSPredicate(format: "familyName LIKE[cd] 'parker'")

contactPicker.predicateForEnablingContact = predicate

Page 110: Introducing the Contacts Framework · Partial Contacts let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey] John givenName Appleseed familyName phoneNumbers john@example.com

Picking ContactsPredicates

Page 111: Introducing the Contacts Framework · Partial Contacts let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey] John givenName Appleseed familyName phoneNumbers john@example.com

Picking ContactsPredicates

predicateForSelectionOfContact

• Which contacts are returned when tapped, others push the card

Page 112: Introducing the Contacts Framework · Partial Contacts let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey] John givenName Appleseed familyName phoneNumbers john@example.com

Picking ContactsPredicates

predicateForSelectionOfContact

• Which contacts are returned when tapped, others push the card

predicateForSelectionOfProperty

• Which properties are returned when tapped, others perform the default action• Evaluated on CNContactProperty

Page 113: Introducing the Contacts Framework · Partial Contacts let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey] John givenName Appleseed familyName phoneNumbers john@example.com

Picking ContactsPredicates

predicateForSelectionOfContact

• Which contacts are returned when tapped, others push the card

predicateForSelectionOfProperty

• Which properties are returned when tapped, others perform the default action• Evaluated on CNContactProperty

Coherence between predicates and delegate methods

Page 114: Introducing the Contacts Framework · Partial Contacts let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey] John givenName Appleseed familyName phoneNumbers john@example.com

Viewing ContactsCNContactViewController

Page 115: Introducing the Contacts Framework · Partial Contacts let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey] John givenName Appleseed familyName phoneNumbers john@example.com

Viewing ContactsCNContactViewController

One class to replace• ABPersonViewController

• ABNewPersonViewController

• ABUnknownPersonViewController

Page 116: Introducing the Contacts Framework · Partial Contacts let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey] John givenName Appleseed familyName phoneNumbers john@example.com

Viewing ContactsCNContactViewController

Page 117: Introducing the Contacts Framework · Partial Contacts let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey] John givenName Appleseed familyName phoneNumbers john@example.com

Viewing ContactsCNContactViewController

Use appropriate creation method

Page 118: Introducing the Contacts Framework · Partial Contacts let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey] John givenName Appleseed familyName phoneNumbers john@example.com

Viewing ContactsCNContactViewController

Use appropriate creation method• viewControllerForContact:

Page 119: Introducing the Contacts Framework · Partial Contacts let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey] John givenName Appleseed familyName phoneNumbers john@example.com

Viewing ContactsCNContactViewController

Use appropriate creation method• viewControllerForContact:

• viewControllerForNewContact:

Page 120: Introducing the Contacts Framework · Partial Contacts let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey] John givenName Appleseed familyName phoneNumbers john@example.com

Viewing ContactsCNContactViewController

Use appropriate creation method• viewControllerForContact:

• viewControllerForNewContact:

• viewControllerForUnknownContact:

Page 121: Introducing the Contacts Framework · Partial Contacts let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey] John givenName Appleseed familyName phoneNumbers john@example.com

Viewing ContactsCNContactViewController

Use appropriate creation method• viewControllerForContact:

• viewControllerForNewContact:

• viewControllerForUnknownContact:

Page 122: Introducing the Contacts Framework · Partial Contacts let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey] John givenName Appleseed familyName phoneNumbers john@example.com

Viewing ContactsCNContactViewController

Use appropriate creation method• viewControllerForContact:

• viewControllerForNewContact:

• viewControllerForUnknownContact:

Always out of process

Page 123: Introducing the Contacts Framework · Partial Contacts let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey] John givenName Appleseed familyName phoneNumbers john@example.com

Viewing ContactsCNContactViewController

Use appropriate creation method• viewControllerForContact:

• viewControllerForNewContact:

• viewControllerForUnknownContact:

Always out of processContact must be fetched with descriptorForRequiredKeys

Page 124: Introducing the Contacts Framework · Partial Contacts let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey] John givenName Appleseed familyName phoneNumbers john@example.com

Viewing ContactsExample

let contact = try contactStore.unifiedContactWithIdentifier(identifier,keysToFetch: [CNContactViewController.descriptorForRequiredKeys])

Page 125: Introducing the Contacts Framework · Partial Contacts let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey] John givenName Appleseed familyName phoneNumbers john@example.com

Viewing ContactsExample

let contact = try contactStore.unifiedContactWithIdentifier(identifier,keysToFetch: [CNContactViewController.descriptorForRequiredKeys])

let viewController = CNContactViewController(forContact: contact)

Page 126: Introducing the Contacts Framework · Partial Contacts let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey] John givenName Appleseed familyName phoneNumbers john@example.com

Viewing ContactsExample

let contact = try contactStore.unifiedContactWithIdentifier(identifier,keysToFetch: [CNContactViewController.descriptorForRequiredKeys])

let viewController = CNContactViewController(forContact: contact)

viewController.contactStore = self.contactStore viewController.delegate = self

Page 127: Introducing the Contacts Framework · Partial Contacts let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey] John givenName Appleseed familyName phoneNumbers john@example.com

Viewing ContactsExample

let contact = try contactStore.unifiedContactWithIdentifier(identifier,keysToFetch: [CNContactViewController.descriptorForRequiredKeys])

let viewController = CNContactViewController(forContact: contact)

viewController.contactStore = self.contactStore viewController.delegate = self

self.pushViewController(viewController)

Page 128: Introducing the Contacts Framework · Partial Contacts let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey] John givenName Appleseed familyName phoneNumbers john@example.com

Viewing ContactsExample

let contact = try contactStore.unifiedContactWithIdentifier(identifier,keysToFetch: [CNContactViewController.descriptorForRequiredKeys])

let viewController = CNContactViewController(forContact: contact)

viewController.contactStore = self.contactStore viewController.delegate = self

self.pushViewController(viewController)

func contactViewController(vc, didCompleteWithContact: contact) { // do something with the modified contact }

Page 129: Introducing the Contacts Framework · Partial Contacts let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey] John givenName Appleseed familyName phoneNumbers john@example.com

DemoPicking and Viewing Contacts

Meow

Page 130: Introducing the Contacts Framework · Partial Contacts let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey] John givenName Appleseed familyName phoneNumbers john@example.com

A new modern Contacts APICommon across all platforms Adopt now!

Summary

Page 131: Introducing the Contacts Framework · Partial Contacts let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey] John givenName Appleseed familyName phoneNumbers john@example.com

More Information

DocumentationContacts Framework ReferenceContactsUI Framework Referencehttp://developer.apple.com/library

Technical SupportApple Developer Forumshttp://developer.apple.com/forums

General InquiriesPaul Marcos, App Frameworks [email protected]

Page 132: Introducing the Contacts Framework · Partial Contacts let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey] John givenName Appleseed familyName phoneNumbers john@example.com

Labs

Contacts, Calendar and Reminders Lab Frameworks Lab A Thursday 4:30PM

Contacts, Calendar and Reminders Lab Frameworks Lab A Friday 9:00AM

Page 133: Introducing the Contacts Framework · Partial Contacts let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey] John givenName Appleseed familyName phoneNumbers john@example.com