#TECH

Why Contacts Framework of iOS 9 is better than the old AddressBook Framework?

Contacts Framework of iOS 9

“Contacts Framework” came up with iOS 9.0 replacing the older Framework “AddressBook”. Those who have used the previous framework must have faced the difficulties to understand and manage the framework.

As new Contacts framework is brought up by Apple, we found it more straightforward and easier to manage too. It is much easier to understand even for naive developers. We can create, fetch and update a contact in no time. Also, the development time will get reduced while using this new Contacts framework and the code will be easier to manage and modify. So, we iOS developers, can breathe some air and play with the phone contacts.

Through this blog you will get to understand the difference between the new framework and the older AddressBook. Let us first quickly see what all we will cover in this blog.

What we will cover :

  1. How to ask for privacy permissions from user for getting contacts from the phone?
  2. How to fetch contacts from the device?
  3. How to save contacts to the device?

If your project is supporting iOS 8.0 then you will be using Addressbook framework and Contacts framework both. So, we will cover all this by using both Contacts framework and AddressBook framework to compare the differences between them.

So folks, let’s get started.

First, we will look at how to ask for permissions from the user for getting contact access.

Permissions:

There are four types of contact authorization states of the app represented by the CNAuthorizationStatus, which is an enum. The four values it can take are:

  1. Not determined: This is the state when the user installs the app and opens app for the first time. At this time the user has not allowed or denied the access to the device contacts.
  2. Denied: This is the state when the user has denied the access to the contacts before. Only user can change this from the device settings . So, in this case we can navigate user to the device settings to allow contact access.
  3. Restricted: In this case application cannot access the contacts and also user cannot enable it from the device settings. It is because some other restrictions might be active.
  4. Authorized: This is the state when the user has allowed the application to have access of the device contacts database. And the app can perform further functionalities accordingly.

For Contacts Framework

func contactsPermission(vc: UIViewController, completion: (() -> ())?) {  
 let status = CNContactStore.authorizationStatusForEntityType(.Contacts)  
       switch status {  
           case .Authorized:  
                  completion?()  
           case .Restricted, .Denied:  
                  completion?()  
          // Open Settings of the device   
           case .NotDetermined:  
                 CNContactStore().requestAccessForEntityType(.Contacts, completionHandler: {  
                      success, error in  
                      self.completion?()  
                 })
       }
 }

 

For Addressbook framework

func contactsPermission(vc: UIViewController, completion: (() -> ())?) {  
     let status = ABAddressBookGetAuthorizationStatus()  
     switch status {  
         case .Authorized:  
             completion?()  
         case .Restricted, .Denied:  
             completion?()  
       // Open Settings of the device  
         case .NotDetermined:  
             ABAddressBookRequestAccessWithCompletion(nil) { success in  
                self.completion?()  
             }  
     }  
   }  

 

Fetching Contacts:

The fundamental classes that we will be using while working with contacts is the CNContactStore in Contacts Framework and AddressBook in Address Framework.

These classes represent the device contact database. They are the ones which coordinate between the application and the actual database.

They perform the following two functions :

  1. Fetching Contacts from the device database.
  2. Saving the contacts to the device or updating the already existing contacts

For using Contacts Framework you have to import the framework as mentioned below:

import Contacts

 

Fetching Contacts for iOS 9.0: If you are supporting versions below iOS 9.0, you will have to check for the iOS 9.0 availability.

@available(iOS 9.0, *)  
   func fetchContactsFromPhonebook() -> [CNContact] {  
     
        let contactStore = CNContactStore()  
        let keysToFetch = [  
           CNContactFormatter.descriptorForRequiredKeysForStyle(.FullName),  
           CNContactPhoneNumbersKey, CNContactEmailAddressesKey]  
           // Get all the containers  
           var allContainers: [CNContainer] = []  
         do {  
               allContainers = try contactStore.containersMatchingPredicate(nil)  
         } catch {  
               print("Error fetching containers")  
         }  
     
        var results: [CNContact] = []  
     
     // Iterate all containers and append their contacts to our results array  
        for container in allContainers {  
           let fetchPredicate = CNContact.predicateForContactsInContainerWithIdentifier(container.identifier)  
           
           do {  
              let containerResults = try contactStore.unifiedContactsMatchingPredicate(fetchPredicate, keysToFetch: keysToFetch)  
              results.appendContentsOf(containerResults)  
           } catch {  
           print("Error fetching results for container")  
           }
        }
     return results  
   }

So, this is how we fetch phone contacts using Contacts framework. This is a lot easier as compared to the Addressbook framework. Wondering why? Because itโ€™s a very complex and lengthy code and it will consume the scope of this blog. Read how to fetch contacts using Addressbook framework here.

Creating a new contact and saving it:

So far, we have discussed how we prompt the user for the Authorization, how to fetch contacts from the device. However, there is still one thing that needs to be discussed, that is, how to create a new contact programmatically and store it to the database. We will demonstrate this by using both the frameworks.

Using Contacts Framework:

For Contacts Framework we need CNMutableContact which is similar to CNContact. It also represents a single contact and all of its properties.

However, CNMutableContact allows to assign new values to the properties of a contact, and therefore create a new one or update an existing contact.

We will have to import ContactsUI framework to our class.

import ContactsUI

 

The below function is for a creating a new contact and saving to the device contact Database.

func saveContact() {  

     let firstName = "Carl"  
     let lastName = "Junior"  
     let number = "9999345793"  
     let email = "carl@quovantis.com"  
     let contactStore = CNContactStore()  
     let contact = CNMutableContact()  
     contact.familyName = lastName  
     contact.givenName = firstName  
     let phoneNumber = CNPhoneNumber(stringValue:number)  
     let homePhone = CNLabeledValue(label: CNLabelHome, value: phoneNumber)  
     contact.phoneNumbers = [homePhone]  
     let homeEmail = CNLabeledValue(label: CNLabelHome, value: email)  
     contact.emailAddresses = [homeEmail]  
     let vc = CNContactViewController(forUnknownContact: contact)  
     vc.delegate = self  
     vc.contactStore = contactStore  
     vc.title = "Contact Info"  
     
     self.navigationController?.pushViewController(vc, animated: true)  
   }  

 

We will have to conform our class, where we are writing our save contact logic, to the CNContactViewControllerDelegate protocol and then implement its function in our code. Below is the function :

func contactViewController(viewController: CNContactViewController, didCompleteWithContact contact: CNContact?) {  
     viewController.dismissViewControllerAnimated(true, completion: nil)  
   }  

 

This delegate is called when the contact we created is saved. Hence we can dismiss the CNContactViewController which we presented.

If you are supporting iOS 8.0 in your app then you will have to do this by using Addressbook Framework also.

So, now we will show how to create and save contacts using Addressbook Framework for iOS 8.0.

Using AddressBook Framework:

First, we will have to import AddressBookUI framework to our class.

import AddressBookUI

func saveContact() {  
     let firstName = "Carl"  
     let lastName = "Junior"  
     let number = "9999345793"  
     let email = "carl@quovantis.com"
     
     let newPerson: ABRecordRef = ABPersonCreate().takeRetainedValue()  
     ABRecordSetValue(newPerson, kABPersonFirstNameProperty, firstName , nil)  
     ABRecordSetValue(newPerson, kABPersonLastNameProperty, lastName , nil)  
     
     let mutliValuePhone:ABMutableMultiValueRef = ABMultiValueCreateMutable(UInt32(kABMultiStringPropertyType)).takeRetainedValue()  
     ABMultiValueAddValueAndLabel(mutliValuePhone, number , kABPersonPhoneMobileLabel, nil)  
     ABRecordSetValue(newPerson, kABPersonPhoneProperty, mutliValuePhone , nil)  
     
     let mutliValueEmail:ABMutableMultiValueRef = ABMultiValueCreateMutable(UInt32(kABMultiStringPropertyType)).takeRetainedValue()  
     ABMultiValueAddValueAndLabel(mutliValueEmail, email , kABWorkLabel , nil)  
     ABRecordSetValue(newPerson, kABPersonEmailProperty, mutliValueEmail , nil)  
     
     let vc = ABNewPersonViewController()  
     vc.displayedPerson = newPerson  
     vc.newPersonViewDelegate = self  
     
     let navVC = UINavigationController(rootViewController: vc)  
     presentViewController(navVC, animated: true, completion: nil)  
   }  

 

We will have to conform our class, where we are writing the save contact logic, to the ABNewPersonViewControllerDelegate protocol and then implement its function in our code. Below is the function :

func newPersonViewController(newPersonView: ABNewPersonViewController, didCompleteWithNewPerson person: ABRecord?) {  
     newPersonView.dismissViewControllerAnimated(true, completion: nil)  
   }

 

Summary:

So we discussed how to ask user for contacts permissions, fetch contacts from the device and save the new contacts to the device.

We found that there is a substantial change between the two frameworks. We can see that with the introduction to Contacts framework, how easy it has become to work with contacts.

I hope I was able to make a point and show why Contacts framework is better than AddressBook framework. I wish you enjoyed reading this and I hope you will find it useful.

Have great learning days ahead! ๐Ÿ™‚

You might also like