Address book frame have been using for accessing and updating user's contact books since iOS 2.0. From iOS 9, there is a new framework called Contacts that replaces addressBook.framebook, provides object orientated interfaces and additional features such as searching and filtering contacts.
A object that represented a contact in the contact book
A object that represented a contact in the contact book and the properties are mutable. Used in adding and update contacts.
A value of a key of certain properties of CNContact
A cooriindater to cache any adding and updating operations to contacts
Can be cache multiple actions before executing. be aware of CNMutableContact not changing when writing into Contacts
//Create 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"
contact.phoneNumbers = [CNLabeledValue(
label: CNLabelPhoneNumberiPhone,
value: CNPhoneNumber(stringValue: "(408) 555-0126"))]
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)]
let birthday = NSDateComponents()
birthday.day = 1
birthday.month = 4
birthday.year = 1988 // can omit for a year-less birthday
let saveRequest = CNSaveRequest()
saveRequest.addContact(john, toContainerWithIdentifier: nil)
try store.executeSaveRequest(saveRequest)
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)
//Getting info. fron a contact
let fullName = CNContactFormatter.stringFromContact(contact, style: .FullName)
let postalString = CNPostalAddressFormatter.stringFromPostalAddress(address)
//matching any names contains "Appleseed"
let predicate = CNContact.predicateForContactsMatchingName("Appleseed")
//getting contacts given name and family name
let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey]
// We can also use formatter to fetch the names
let keysToFetch = [CNContactFormatter.descriptorForRequiredKeysForStyle(.FullName),
CNContactEmailAddressesKey]
// get a instance of contact store. Don't need to strong reference
let store = CNContactStore()
//This may be a long running tasks, suggested to put the fetching into background threads
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)")
}
//call this to get permission of accessing contacts
CNContactStore.requestAccessForEntityType(_, completionHandler:)
//call this to check if the key available for fetching
if (contact.isKeyAvailable(CNContactPhoneNumbersKey)) {
//...
}
CNContactPickerViewController
and CNContactViewController
will replace address book ui framework
//filter the contacts in the picker
let predicate = NSPredicate(format: "familyName LIKE[cd] 'parker'")
contactPicker.predicateForEnablingContact = predicate
predicateForSelectionOfContact
to indicate Which contacts are returned when tapped, others push the detail card
predicateForSelectionOfProperty
to indicate Which properties are returned when tapped, others perform the default action based on CNContactProperty
Coherence between predicates and delegate methods as it does not make sense to filter the properties that you dont want to get deleget methods
viewing contacts
//init methods for different status of contact
viewControllerForContact:
viewControllerForNewContact:
viewControllerForUnknownContact:
not required contact permisson (not showing contact dislog)
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
}