As every iOS release, the version 9, which is officially here for just a few weeks, presents new features and improvements to existing technologies for both users and developers. As we’ve all witnessed, there’s a number of new stuff that has been first-introduced in this version, but there are changes and updates to existing frameworks and libraries as well. Additionally, and that’s always surprising, there are cases where old APIs are left aside and become deprecated, making room for new ones that have been implemented from ground up to fill in the gap instead. The greatest example in iOS 9 is the all brand new Contacts framework, which is here to replace the old AddressBook framework in a fashion modern, simple and a lot more straightforward.
Every developer that has dealt with the AddressBook API in the past can definitely say that it wasn’t the most easy part of the iOS SDK to work with. In general, the AddressBook was difficult to understand and manage, and that fact was even more intense in new developers. All that belongs to history, as the new Contacts framework is way simpler to understand and use; contacts can be fetched, created or updated in no time at all, the contacts-related development time can be dramatically decreased, changes and modification can be done really fast.
In the next few paragraphs we’ll highlight the most important aspects of the Contacts framework. I won’t go into much details, as you can find them all in the official Apple documentation, and the WWDC 2015 session 223 video.
So, first of all, I’ll begin by something crucial, and that is the user privacy. Users are always being asked if they grant access to their contacts data through an application. If they do so, then the app can freely interact with the user’s contacts database. If, on the other hand, users prohibit access to the contacts data, then this decision must be respected by the app and not interact with it at all. In a while we’ll talk more specifically about it, and we’ll see how all possible situations are handled programmatically. Furthermore, keep in mind that the user is always eligible to change the authorization state of the app through the device Settings, so you should always check if your app has the required permissions to access the contacts data or not right before you perform any related task.
The main source of contacts data is always the database existing in a device. However, the Contacts framework does not lookup just there when an app asks for contact data. In fact, it searches for contacts in other sources too, like your iCloud account (if you’re connected to it of course), and returns back to the app unified contacts that originate from various sources. This is quite useful, as you don’t have to initiate separate searches for contacts residing in databases other than the device’s. You have them all at once, and you manage them as you like.
The Contacts framework has a number of classes that serve specific purposes. All of them have their importance, but the one that is used the most, is called CNContactStore. This one represents the contacts database programmatically, and provides various methods for performing tasks like fetching, saving or updating records, authorization check and authorization request, and many more. A single contact is represented by the CNContact class, but keep in mind that the properties of that class are immutable. If you want to create a new contact or update an existing one, you must use the CNMutableContact one. Note that when dealing with the Contacts framework, and especially when fetching contacts, you should always perform those tasks in background threads. If a contact fetching task takes too much time and is working in the main thread, then your app may become unresponsive, and eventually end up to a bad user experience.
Rarely all of the contact properties are really needed when importing contacts into an app. Fetching all data for all contacts existing in all sources that the Contacts framework searches into, can be proved a resource-eating process, so you should avoid doing that unless you’re sure that you’re going to use all of the data pieces, up to the last one. Thankfully the Contacts framework provides ways for fetching partial results, meaning just a subset of properties regarding a contact. For example, you could ask only for the first and last name, the home email address, and the home phone number, and save that way a lot of resources by leaving aside all that data you don’t really need.
Besides all the programmatic access that the Contacts framework provides, it also supports some default UI that can be incorporated in applications and have that way direct and visual access to contacts. The provided UI is pretty much same to the Contacts app, so that means that there’s a contact picker view controller along with the details card that can be used to pick contacts and properties (it can be customized up to a level), and a contacts view controller to display the contact details and perform certain actions (for example, to make a call).
All of the above are aspects that we’ll see in details in the following parts of this tutorial. Once again, visit the official documentation for additional information on what I presented or what I’ll present from now on. Let’s see now what the demo application is going to be, and then let’s get started dealing with the Contacts framework classes. You’ll find out that it’s easy and funny messing with this new framework.