{"id":3525,"date":"2017-07-27T11:02:21","date_gmt":"2017-07-27T05:32:21","guid":{"rendered":"https:\/\/www.innovationm.com\/blog\/?p=3525"},"modified":"2017-07-27T11:02:21","modified_gmt":"2017-07-27T05:32:21","slug":"contacts-framework-vs-addressbook-swift-3-0","status":"publish","type":"post","link":"https:\/\/www.innovationm.com\/blog\/contacts-framework-vs-addressbook-swift-3-0\/","title":{"rendered":"Contacts Framework Vs AddressBook Swift 3.0"},"content":{"rendered":"<h2>Contacts Framework<\/h2>\n<p>Contacts Framework came up \u00a0with iOS 9.0 . This framework provide Swift and Objective-C\u00a0API to\u00a0access the\u00a0user\u2019s contact information.<\/p>\n<h2>AddressBook Framework<\/h2>\n<p>AddressBook Framework was used in iOS 8 and earlier for access user&#8217;s contact information .<\/p>\n<p>Through this blog you will get to understand working with Contacts and AddressBook Framework. \u00a0So before accessing the contact you have to take permission from user to access contact.<\/p>\n<h3>Permissions:<\/h3>\n<p>There are four type of permission states:<\/p>\n<ol>\n<li><strong> Not determined: <\/strong>\u00a0When user installs the app and open for the first time.<\/li>\n<li><strong><b>Denied: <\/b><\/strong>When user denied to access contact.<\/li>\n<li><strong><b>Restricted: \u00a0<\/b><\/strong>This state can not be handle by user. This might be another reason to be restricted.<\/li>\n<li><b>Authorized:\u00a0<\/b>\u00a0When user allows to access contact.<\/li>\n<\/ol>\n<h3>Ask permission from user to access contact:<\/h3>\n<h4>Contacts Framework:<\/h4>\n<pre class=\"lang:swift decode:true\">public func checkPermissions() throws {\r\n\r\n    let status = CNContactStore.authorizationStatus(for: .contacts)\r\n    switch status {\r\n    case .denied:\r\n        throw ContactAccessError(description: \"Access Denied\")\r\n    case .notDetermined:\r\n        \/\/ In case of not determined request for access\r\n        \/\/ If allowed it will return success otherwise return error\r\n        contactStore.requestAccess(for: .contacts, completionHandler:{ success, error in\r\n            if success {\r\n                print(\"Access Allowed\")\r\n            }\r\n        })       \r\n    default:\r\n        break\r\n    }\r\n}<\/pre>\n<p>In Contact Framework <strong>CNContactStore\u00a0<\/strong>provides ways to execute fetch and save requests. <strong>authorizationStatus(for:) \u00a0<\/strong>returns the current authorization status to access the contact data. <strong>requestAccess(for:completionHandler:)\u00a0<\/strong>requests access to user&#8217;s contacts. \u00a0<strong>ContactAccessError\u00a0<\/strong> is a custom error.<\/p>\n<pre class=\"lang:swift decode:true \">class ContactAccessError: LocalizedError {\r\n    \r\n    private var desc = \"\"\r\n    \r\n    init(description: String) {\r\n        desc = description\r\n    }\r\n    \r\n    var errorDescription: String? {\r\n        get {\r\n            return self.desc\r\n        }\r\n    }\r\n}<\/pre>\n<p>&nbsp;<\/p>\n<h4>AddressBook Framework:<\/h4>\n<pre class=\"lang:default decode:true\"> func contactsPermission(completion: @escaping (Bool) -&gt; Void) {\r\n    let authorizationStatus = ABAddressBookGetAuthorizationStatus()\r\n    switch authorizationStatus {\r\n    case .authorized:\r\n        completion(true)\r\n            \r\n    case .restricted:\r\n        completion(false)\r\n            \r\n    case .denied:\r\n        completion(false)\r\n            \r\n    case .notDetermined:\r\n        self.getAccessOfAddressBook()\r\n    }\r\n  }\r\n\r\n  func getAccessOfAddressBook() {\r\n        let addressBookRef: ABAddressBook = ABAddressBookCreateWithOptions(nil, nil).takeRetainedValue()\r\n        ABAddressBookRequestAccessWithCompletion(addressBookRef, {(granted: Bool, error: CFError?) in\r\n            if granted{\r\n                print(\"Access granted\")\r\n            } else {\r\n                print(\"Access not granted\")\r\n            }\r\n        })\r\n    }<\/pre>\n<p>In AdressBook \u00a0<strong>ABAddressBookGetAuthorizationStatus() <\/strong>return current authorization status. if you will open the application first time, then the auterization status will be\u00a0<strong>notDetermined.\u00a0<\/strong>So in this case you have to request to access contact. In AddressBook Framework first you have to get the reference of AddressBook to request for access contacts.<\/p>\n<p class=\"p1\"><span class=\"s1\"><strong> ABAddressBookCreateWithOptions(_ options:, _ error: )<\/strong>\u00a0 c<\/span><span class=\"s1\">reates a new address book object (reference) with data from the Address Book database. This object is unmanaged( ie memory management is not\u00a0controlled by the Swift runtime system).\u00a0<\/span><\/p>\n<p><strong>takeRetainedValue()\u00a0<\/strong>get the value of an unmanaged reference as a managed reference (ie you want ARC to take care of releasing the object when you&#8217;re done).<\/p>\n<p class=\"p1\"><strong><span class=\"s1\"> ABAddressBookRequestAccessWithCompletion(<\/span><span class=\"s2\">_<\/span><span class=\"s1\"> addressBook: <\/span><span class=\"s1\">, <\/span><span class=\"s2\">_<\/span><span class=\"s1\"> completion:\u00a0<\/span><span class=\"s1\">)\u00a0r<\/span><\/strong><span class=\"s1\">equests access to user&#8217;s contacts.<\/span><\/p>\n<p><strong>Note:\u00a0<\/strong><em>One more thing you will have to do in your project to access user&#8217;s contact is:- \u00a0 \u00a0 define\u00a0<strong>Privacy &#8211; Contacts Usage Description <\/strong>key in info.plist file with description.<\/em><\/p>\n<p>When you run the app for the first time and try to save, fetch or update contact, you should see the following alert.<\/p>\n<p><img fetchpriority=\"high\" decoding=\"async\" class=\"size-medium wp-image-3605 aligncenter\" src=\"https:\/\/www.innovationm.com\/blog\/wp-content\/uploads\/2017\/07\/Simulator-Screen-Shot-19-Jul-2017-2.57.29-PM-169x300.png\" alt=\"\" width=\"169\" height=\"300\" srcset=\"https:\/\/www.innovationm.com\/blog\/wp-content\/uploads\/2017\/07\/Simulator-Screen-Shot-19-Jul-2017-2.57.29-PM-169x300.png 169w, https:\/\/www.innovationm.com\/blog\/wp-content\/uploads\/2017\/07\/Simulator-Screen-Shot-19-Jul-2017-2.57.29-PM-768x1365.png 768w, https:\/\/www.innovationm.com\/blog\/wp-content\/uploads\/2017\/07\/Simulator-Screen-Shot-19-Jul-2017-2.57.29-PM-576x1024.png 576w, https:\/\/www.innovationm.com\/blog\/wp-content\/uploads\/2017\/07\/Simulator-Screen-Shot-19-Jul-2017-2.57.29-PM-624x1109.png 624w, https:\/\/www.innovationm.com\/blog\/wp-content\/uploads\/2017\/07\/Simulator-Screen-Shot-19-Jul-2017-2.57.29-PM.png 1242w\" sizes=\"(max-width: 169px) 100vw, 169px\" \/><\/p>\n<p><strong><br \/>\nWhat happens if the user doesn\u2019t allow access?<\/strong><\/p>\n<p>If \u00a0user don&#8217;t allow to access contact, in this case \u00a0your app will stuck forever. So in case of denied you can so an alert \u00a0to user to allows access contact.<\/p>\n<pre class=\"lang:default decode:true\">func showPermissionAlert() {\r\n    let alert = UIAlertController(title: \"\", message: \"Allow App to access contacts\"\r\n        , preferredStyle: .alert)\r\n    let cancelAction = UIAlertAction(title: \"Cancel\", style: .cancel, handler: nil) \r\n    let settingAction = UIAlertAction(title: \"Settings\", style: .default, handler: { (action) in\r\n          \/\/ Open Settings, right to the page with your app\u2019s permissions\r\n          openSetings()\r\n    })\r\n    \r\n    alert.addAction(cancelAction)\r\n    alert.addAction(settingAction)\r\n    alert.preferredAction = settingAction\r\n   self.present(alert, animated: true, completion: nil)   \r\n}<\/pre>\n<p><img decoding=\"async\" class=\"size-medium wp-image-3606 aligncenter\" src=\"https:\/\/www.innovationm.com\/blog\/wp-content\/uploads\/2017\/07\/Simulator-Screen-Shot-19-Jul-2017-2.56.14-PM-169x300.png\" alt=\"\" width=\"169\" height=\"300\" srcset=\"https:\/\/www.innovationm.com\/blog\/wp-content\/uploads\/2017\/07\/Simulator-Screen-Shot-19-Jul-2017-2.56.14-PM-169x300.png 169w, https:\/\/www.innovationm.com\/blog\/wp-content\/uploads\/2017\/07\/Simulator-Screen-Shot-19-Jul-2017-2.56.14-PM-768x1365.png 768w, https:\/\/www.innovationm.com\/blog\/wp-content\/uploads\/2017\/07\/Simulator-Screen-Shot-19-Jul-2017-2.56.14-PM-576x1024.png 576w, https:\/\/www.innovationm.com\/blog\/wp-content\/uploads\/2017\/07\/Simulator-Screen-Shot-19-Jul-2017-2.56.14-PM-624x1109.png 624w, https:\/\/www.innovationm.com\/blog\/wp-content\/uploads\/2017\/07\/Simulator-Screen-Shot-19-Jul-2017-2.56.14-PM.png 1242w\" sizes=\"(max-width: 169px) 100vw, 169px\" \/><\/p>\n<pre class=\"lang:default decode:true\">func openSettings() {\r\n   let url = URL(string: UIApplicationOpenSettingsURLString)\r\n   UIApplication.shared.openURL(url!)\r\n }<\/pre>\n<p>This will send the user to the Settings app, right to the page with your app\u2019s permissions.<\/p>\n<p><img decoding=\"async\" class=\"size-medium wp-image-3552 aligncenter\" src=\"https:\/\/www.innovationm.com\/blog\/wp-content\/uploads\/2017\/07\/Simulator-Screen-Shot-12-Jul-2017-4.40.00-PM-169x300.png\" alt=\"\" width=\"169\" height=\"300\" srcset=\"https:\/\/www.innovationm.com\/blog\/wp-content\/uploads\/2017\/07\/Simulator-Screen-Shot-12-Jul-2017-4.40.00-PM-169x300.png 169w, https:\/\/www.innovationm.com\/blog\/wp-content\/uploads\/2017\/07\/Simulator-Screen-Shot-12-Jul-2017-4.40.00-PM-577x1024.png 577w, https:\/\/www.innovationm.com\/blog\/wp-content\/uploads\/2017\/07\/Simulator-Screen-Shot-12-Jul-2017-4.40.00-PM-624x1108.png 624w, https:\/\/www.innovationm.com\/blog\/wp-content\/uploads\/2017\/07\/Simulator-Screen-Shot-12-Jul-2017-4.40.00-PM.png 640w\" sizes=\"(max-width: 169px) 100vw, 169px\" \/><\/p>\n<h2>Save New Contacts<\/h2>\n<h3>Contacts Framework:<\/h3>\n<p>Here I have created an object of model class <strong>ContactDetail<\/strong> which holds the detail of new contact like first name, last name, contact number, email etc.<\/p>\n<pre class=\"lang:default decode:true\"> contactInfo = ContactDetail(firstName: textFieldFirstName.text, lastName: textFieldLastName.text, PhnNo: textFieldPhoneNumber.text, street: textFieldStreet.text, city: textFieldCity.text, state: textFieldState.text, zipCode: textFieldZipCode.text, homeEmail: textFieldHomeEmail.text, workEmail: textFieldWorkEmail.text)<\/pre>\n<p>The below function is for creating the new contact. \u00a0First you have \u00a0to create a <strong>CNMutableContact<\/strong> object and assign the givenName, familyName etc which you want to save.\u00a0\u00a0For contact properties that can have multiple values, such as phone numbers or email addresses, an array of <strong>CNLabeledValue<\/strong>\u00a0objects is used. \u00a0Here <strong>CNPhoneNumber<\/strong> class \u00a0returns a new phone number object initialized with the specified phone number string.<\/p>\n<pre class=\"lang:default decode:true\"> func createContact() {\r\n    let contact = CNMutableContact()\r\n    contact.givenName = contactInfo.firstName\r\n    contact.familyName = contactInfo.lastName\r\n    contact.phoneNumbers = [CNLabeledValue(label: CNLabelPhoneNumberiPhone, value: CNPhoneNumber(stringValue: contactInfo.PhnNo))]\r\n        \r\n    let homeAddress = CNMutablePostalAddress()\r\n    homeAddress.street = contactInfo.street\r\n    homeAddress.city = contactInfo.city\r\n    homeAddress.state = contactInfo.state\r\n    homeAddress.postalCode = contactInfo.zipCode\r\n    contact.postalAddresses = [CNLabeledValue(label:CNLabelHome, value:homeAddress)]\r\n        \r\n    let homeEmail = CNLabeledValue(label: CNLabelHome, value: (contactInfo.homeEmail) as NSString!)\r\n    let workEmail = CNLabeledValue(label: CNLabelWork, value: (contactInfo.workEmail) as NSString!)\r\n    contact.emailAddresses = [homeEmail, workEmail]\r\n        \r\n    \/\/ Saving the newly created contact\r\n    saveContact(contact: contact) { [weak self] result in\r\n        if result {\r\n           \/\/ show success alert\r\n           let contactDetailVC = CNContactViewController(for: contact)\r\n           contactDetailVC.contactStore = CNContactStore()\r\n           contactDetailVC.title = \"Contact Info\"\r\n           self?.navigationController?.pushViewController(contactDetailVC, animated: true)\r\n        } else {\r\n           \/\/ show something went wrong\r\n        }\r\n    }      \r\n}\r\n<\/pre>\n<p><strong>Note:<\/strong> <em>Here <strong>CNContactViewController(for: contact) <\/strong>is used to show saved contact . This class \u00a0 is of ContactsUI Framework. So you have to import ContactsUI framework. \u00a0The CNContactViewController \u00a0class implements the view to display a contact. CNContactViewController can display a new contact, unknown contact, or existing contact.<\/em><\/p>\n<pre class=\"lang:swift decode:true\">import ContactsUI<\/pre>\n<p>&nbsp;<\/p>\n<p><strong>Note:<\/strong> <em>To proceed any operation on contact <strong>l<\/strong><strong style=\"font-size: 1rem;\">ike save, fetch, update or delete<\/strong><span style=\"font-size: 1rem;\">, \u00a0first you have to\u00a0<\/span><strong style=\"font-size: 1rem;\">check permission<\/strong><span style=\"font-size: 1rem;\">\u00a0by using <\/span><strong style=\"font-size: 1rem;\">checkPermission() <\/strong><span style=\"font-size: 1rem;\">method (discussed above). if access to contact is allowed then the process will proceed further otherwise catch block will execute and an alert will show to allow access contact (<\/span><strong style=\"font-size: 1rem;\">showPermissionAlert() discussed above<\/strong><span style=\"font-size: 1rem;\">).<\/span><\/em><\/p>\n<p>To save contact create\u00a0<strong style=\"font-size: 1rem;\">CNSaveRequest\u00a0<\/strong><span style=\"font-size: 1rem;\">\u00a0object and call its \u00a0<strong>addContact(_:toContainerWithIdentifier:) \u00a0<\/strong><\/span><span style=\"font-size: 1rem;\">method to tell the Contacts framework that you want to create a new contact. By passing <strong>nil<\/strong><\/span><span style=\"font-size: 1rem;\">\u00a0as the identifier, the new contact will be saved in the default contacts group.<\/span><\/p>\n<pre class=\"lang:default decode:true\"> func saveContact(contact: CNMutableContact, completion: @escaping (Bool) -&gt; Void) {  \r\n    do {\r\n        try checkPermissions()\r\n        \r\n        \/\/ Adds the specified contact to the contact store\r\n        let saveRequests = CNSaveRequest()\r\n        let contactStore = CNContactStore()\r\n        saveRequests.add(contact, toContainerWithIdentifier:nil)\r\n        do {\r\n            \r\n            \/\/ Executes a save request and returns success or failure\r\n            try contactStore.execute(saveRequests)\r\n            completion(true)\r\n            \r\n        } catch {\r\n            completion(false)\r\n        }\r\n        \r\n    } catch {\r\n        \/\/ in case of access denied this block will execute\r\n        showPermissionAlert()\r\n    }    \r\n}<\/pre>\n<h3>AddressBook:<\/h3>\n<p>The call to\u00a0<strong><code>ABPersonCreate()<\/code><\/strong>\u00a0creates a reference to a new Address Book record. Once you have that, you can call\u00a0<strong><code>ABRecordSetValue()<\/code><\/strong>\u00a0and pass it the record, the field to change, and the value.\u00a0Since one contact can have multiple phone numbers (home, mobile, etc.) and emails, you have to use<strong>\u00a0ABMutableMultiValue \u00a0<\/strong>reference, which supports multiple values. <strong>\u00a0ABMultiValueAndLabel\u00a0<\/strong><span class=\"s1\">adds a value and its corresponding label to a multivalue property (ie phoneNumbers).\u00a0<\/span>The label\u00a0<strong><code>kABPersonPhoneMainLabel<\/code><\/strong>\u00a0says that this is the contact\u2019s primary number. You can add another label as your requirements. The same step will be follow to create email.\u00a0ABAddressBookAddRecord() \u00a0adds a record to addressBookRef.<\/p>\n<pre class=\"lang:default decode:true\">private func createContact() {\r\n    let addressBookRef: ABAddressBook = ABAddressBookCreateWithOptions().takeRetainedValue() \r\n    let contactDetail: ABRecord = ABPersonCreate().takeRetainedValue()\r\n    ABRecordSetValue(contactDetail, kABPersonFirstNameProperty, contactInfo?.firstName as CFTypeRef!, nil)  \r\n    ABRecordSetValue(contactDetail, kABPersonLastNameProperty, contactInfo?.lastName as CFTypeRef!, nil)\r\n\r\n    let phoneNumbers: ABMutableMultiValue = ABMultiValueCreateMutable(ABPropertyType(kABMultiStringPropertyType)).takeRetainedValue()\r\n    ABMultiValueAddValueAndLabel(phoneNumbers, contactInfo?.PhnNo as CFTypeRef!, kABPersonPhoneMainLabel, nil)\r\n    ABRecordSetValue(contactDetail, kABPersonPhoneProperty, phoneNumbers, nil) \r\n\r\n    let homeEmail:ABMutableMultiValue = ABMultiValueCreateMutable(ABPropertyType(kABMultiStringPropertyType)).takeRetainedValue()\r\n    ABMultiValueAddValueAndLabel(homeEmail, contactInfo.homeEmail as CFTypeRef! , kABHomeLabel , nil)\r\n    ABRecordSetValue(contactDetail, kABPersonEmailProperty, homeEmail , nil)\r\n    \r\n    let workEmail:ABMutableMultiValue = ABMultiValueCreateMutable(ABPropertyType(kABMultiStringPropertyType)).takeRetainedValue()\r\n    ABMultiValueAddValueAndLabel(workEmail, contactInfo.homeEmail as CFTypeRef! , kABWorkLabel , nil)\r\n    ABRecordSetValue(contactDetail, kABPersonEmailProperty, workEmail , nil)\r\n    \r\n    ABAddressBookAddRecord(addressBookRef, contactDetail, nil)\r\n    saveContact(addressBookRef: addressBookRef, contact: contactDetail)\r\n}<\/pre>\n<p>Now contact is only added to reference of Address Book. It is not saved in Address Book database. To save in Address Book implement <strong>saveContact(). \u00a0ABAddressBookHasUnsavedChanges() <\/strong>i<span class=\"s1\">ndicates whether an address book has changes that have not been saved to the Address Book database. <strong>\u00a0ABAddressBookSave()\u00a0<\/strong>save the changes in Address Book.<\/span><\/p>\n<pre class=\"lang:default decode:true\">func saveContact(addressBookRef: ABAddressBook, contact: ABRecord) {\r\n    if ABAddressBookHasUnsavedChanges(addressBookRef){\r\n        let savedToAddressBook = ABAddressBookSave(addressBookRef, nil)\r\n\r\n        if savedToAddressBook {         \r\n            let alertView = UIAlertController(title: nil, message: \"Contact saved Successfuly.\", preferredStyle: .alert)\r\n            alertView.addAction(UIAlertAction(title: \"OK\", style: .default, handler: { _ in\r\n                let personViewController = ABPersonViewController()\r\n                personViewController.displayedPerson = contact\r\n                self.navigationController?.pushViewController(personViewController, animated: true)\r\n            }))\r\n            \r\n            present(alertView, animated: true, completion: nil)\r\n    \r\n        } else {\r\n            print(\"Couldn't save changes.\")\r\n        }\r\n    } else {\r\n        print(\"No changes occurred.\")\r\n    }\r\n}\r\n<\/pre>\n<p><strong>Note:\u00a0<\/strong>Here personViewcontroller is used to display saved contact which is the part of \u00a0AddressBookUI. So you have to import it .<\/p>\n<pre class=\"lang:default decode:true\">import AddressBookUI<\/pre>\n<h2>Fetch Contacts<\/h2>\n<h3>Contacts Framework:<\/h3>\n<pre class=\"lang:default decode:true\">func fetchContactsFromPhonebook() -&gt; [CNContact] {\r\n    let name = textFieldName.text ?? \"\"\r\n    let keysToFetch = [CNContactFormatter.descriptorForRequiredKeys(for: .fullName),\r\n                       CNContactPhoneNumbersKey, CNContactEmailAddressesKey] as [Any]\r\n    \r\n    \r\n    return searchContacts(withName: name, keysToFetch: keysToFetch)\r\n}<\/pre>\n<p>&nbsp;<\/p>\n<pre class=\"lang:default decode:true\">func searchContacts(withName: String, keysToFetch: [CNKeyDescriptor]) -&gt; [CNContact] {\r\n    \r\n    var results: [CNContact] = []\r\n    do {\r\n        try checkPermissions()\r\n        \r\n        \/\/ Fetch data using some predicate\r\n        let predicate: NSPredicate = CNContact.predicateForContacts(matchingName: withName)\r\n        \r\n        \/\/ if you want to fetch only some record of a contact.\r\n        \/\/ Then define key to fetch\r\n        let keys = keysToFetch\r\n        \r\n        do {         \r\n            \/\/ Fetches all unified contacts matching the specified predicate\r\n            let containerResults = try contactStore.unifiedContacts(matching: predicate, keysToFetch: keys)\r\n            results.append(contentsOf: containerResults)\r\n            \r\n        } catch {\r\n            print(error.localizedDescription)\r\n        }\r\n    } catch {\r\n        showPermissionAlert()\r\n    }\r\n    return results\r\n}<\/pre>\n<p>&nbsp;<\/p>\n<p>As discussed earlier you can fetch contacts using the contact <strong>CNContactStore()<\/strong>, which represents the user&#8217;s contacts database. You can add some predicate(any string or character) to fetch contacts. <strong>CNContact<\/strong>\u00a0provides predicates for filtering the contacts you want to fetch .<\/p>\n<p>You can use <strong>keysToFetch<\/strong>\u00a0to limit the contact properties that are fetched. <strong>For example<\/strong> if you want to fetch only name , phone number and email address then pass these \u00a0key in keyToFetch.<\/p>\n<p>The Contacts framework can also perform operations on the fetched contacts, such as formatting contact names. Here in code there is a key <strong>\u00a0CNContactFormatter.descriptorForRequiredKeys(for: .fullName)\u00a0<\/strong>in keyToFetch array. This will format the name of contact. For example if fetched contact <strong>givenName = &#8220;Jhon&#8221;<\/strong> and\u00a0<strong>family<\/strong><strong>Name = &#8220;Rich&#8221;<\/strong> then CNContactFormatter format\u00a0the<strong> fullName = &#8220;Jhon Rich&#8221;.<\/strong><\/p>\n<p><strong>unifiedContactsMatchingPredicate(_:keysToFetch:) <\/strong>method of CNContactStore unified the result. That is if a user has multiple contacts that relate to the same person, they can link these together in the Contacts app. When your app tries to access this user&#8217;s contacts, rather than returning multiple\u00a0<code class=\"inline\">CNContact<\/code>\u00a0instances, the Contacts framework\u00a0<strong>unifies\u00a0<\/strong>these together into one object so your app can display information correctly and interpret it easily.<\/p>\n<h3>AddressBook Framework:<\/h3>\n<pre class=\"lang:default decode:true\">func fetchContactFromAddressBook() -&gt; [ABRecord] {\r\n    var result = [ABRecord]()\r\n    var index = 0\r\n    let addressBookRef = ABAddressBookCreate().takeRetainedValue()\r\n    let allContacts = ABAddressBookCopyArrayOfAllPeople(addressBookRef).takeRetainedValue() as Array\r\n    \r\n    for record in allContacts {\r\n        let currentContact: ABRecord = record\r\n        let currentContactName = ABRecordCopyCompositeName(currentContact).takeRetainedValue() as String\r\n        if currentContactName.contains(textFieldName.text!) {\r\n            result.append(currentContact)\r\n            index += 1\r\n        }\r\n    }\r\n    return result\r\n}<\/pre>\n<p>In AddressBook framework \u00a0you can fetch contact by reference of AddressBook .As discussed earlier \u00a0ABAddressBookCreate give the reference ok AddressBook. Tp fetch all record yo can call <strong>\u00a0ABAddressBookCopyArrayOfAllPeople() <\/strong>method<strong>.\u00a0<\/strong>In AddressBook framework there is no any method to apply predicate . so you have to write the code to compare to find particular result.<\/p>\n<h2>Delete Contact<\/h2>\n<h3>Contacts Framework:<\/h3>\n<pre class=\"lang:default decode:true\"> func deleteContact() {   \r\n    do {\r\n         try checkPermissions() \r\n         let store = CNContactStore()\r\n         let saveRequest = CNSaveRequest()\r\n         saveRequest.delete(newContact)\r\n         do {\r\n              try store.execute(saveRequest)\r\n        \r\n         } catch {\r\n              print(error)\r\n         }\r\n     } catch {\r\n         showPermissionAlert()\r\n     }\r\n}<\/pre>\n<p><strong>Note:<\/strong> I<em>n contacts Framework there is delete(<span class=\"s1\">_<\/span><span class=\"s2\"> contact:<\/span>) method to delete contact. the contact fetched is of <strong>CNContact<\/strong> type . So you have to convert it into <strong>CNMutableContact<\/strong> then pass in delete() method.<\/em><\/p>\n<pre class=\"lang:default decode:true\">let newContact = contactDetail?.mutableCopy() as! CNMutableContact<\/pre>\n<h3>AddressBook Framework:<\/h3>\n<pre class=\"lang:default decode:true\">private func deleteContact() {\r\n    let isRemove = ABAddressBookRemoveRecord(addressBookRef, currentContact, nil)\r\n    print(isRemove)\r\n    let isSaved = ABAddressBookSave(addressBookRef, nil)\r\n    if isSaved {\r\n        let alertView = UIAlertController(title: nil, message: \"Contact deleted Successfully.\", preferredStyle: .alert)   \r\n        alertView.addAction(UIAlertAction(title: \"OK\", style: .default, handler: nil))\r\n        present(alertView, animated: true, completion: nil)      \r\n    }\r\n}<\/pre>\n<p>In AddressBook Framework call \u00a0<strong><span class=\"s1\" style=\"font-size: 1rem;\">ABAddressBookRemoveRecord(<\/span><span class=\"s2\" style=\"font-size: 1rem;\">_<\/span><span class=\"s1\" style=\"font-size: 1rem;\"> addressBook: <\/span><span class=\"s1\" style=\"font-size: 1rem;\">, <\/span><span class=\"s2\" style=\"font-size: 1rem;\">_<\/span><span class=\"s1\" style=\"font-size: 1rem;\"> record: <\/span><span class=\"s1\" style=\"font-size: 1rem;\">, <\/span><span class=\"s2\" style=\"font-size: 1rem;\">_<\/span><span class=\"s1\" style=\"font-size: 1rem;\"> error:)\u00a0<\/span><\/strong><span class=\"s1\" style=\"font-size: 1rem;\">will delete record from addressbookRef but not from the AddressBook database. So after remove call the\u00a0<\/span><span class=\"s1\" style=\"font-size: 1rem;\">ABAddressBookSave(<\/span><span class=\"s2\" style=\"font-size: 1rem;\">_<\/span><span class=\"s1\" style=\"font-size: 1rem;\"> addressBook:<\/span><span class=\"s1\" style=\"font-size: 1rem;\">, <\/span><span class=\"s2\" style=\"font-size: 1rem;\">_<\/span><span class=\"s1\" style=\"font-size: 1rem;\"> error: <\/span><span class=\"s1\" style=\"font-size: 1rem;\">) method to reflect changes in database.<\/span><\/p>\n<h2>Update Contact<\/h2>\n<h3>Contacts Framework:<\/h3>\n<pre class=\"lang:default decode:true\"> func updateContact() {\r\n    do {\r\n         try checkPermissions()\r\n         let store = CNContactStore()\r\n         let saveRequest = CNSaveRequest()\r\n    \r\n          saveRequest.update(newContact)\r\n          do {\r\n               try store.execute(saveRequest)\r\n        \r\n           } catch {\r\n                print(error)\r\n           }\r\n\r\n     } catch {\r\n          showPermissionAlert()\r\n     }\r\n}<\/pre>\n<p>Similar to delete there is update(<span class=\"s1\">_<\/span><span class=\"s2\"> contact:<\/span>) \u00a0method in contact Framework to update existing contact.<\/p>\n<h3>AddressBook Framework:<\/h3>\n<p>To update contact in AddressBook you can use the method ABAddressBookHasUnsavedChanges() of ABAddressBook. If it returns true then call save method to save changes.\u00a0(Similar to Add new contact).<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Contacts Framework Contacts Framework came up \u00a0with iOS 9.0 . This framework provide Swift and Objective-C\u00a0API to\u00a0access the\u00a0user\u2019s contact information. AddressBook Framework AddressBook Framework was used in iOS 8 and earlier for access user&#8217;s contact information . Through this blog you will get to understand working with Contacts and AddressBook Framework. \u00a0So before accessing the [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":3617,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[3,71],"tags":[],"class_list":["post-3525","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-ios","category-mobile"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.4 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Contacts Framework Vs AddressBook Swift 3.0 - InnovationM - Blog<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.innovationm.com\/blog\/contacts-framework-vs-addressbook-swift-3-0\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Contacts Framework Vs AddressBook Swift 3.0 - InnovationM - Blog\" \/>\n<meta property=\"og:description\" content=\"Contacts Framework Contacts Framework came up \u00a0with iOS 9.0 . This framework provide Swift and Objective-C\u00a0API to\u00a0access the\u00a0user\u2019s contact information. AddressBook Framework AddressBook Framework was used in iOS 8 and earlier for access user&#8217;s contact information . Through this blog you will get to understand working with Contacts and AddressBook Framework. \u00a0So before accessing the [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.innovationm.com\/blog\/contacts-framework-vs-addressbook-swift-3-0\/\" \/>\n<meta property=\"og:site_name\" content=\"InnovationM - Blog\" \/>\n<meta property=\"article:published_time\" content=\"2017-07-27T05:32:21+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.innovationm.com\/blog\/wp-content\/uploads\/2017\/07\/Manage-Contacts_1.png\" \/>\n\t<meta property=\"og:image:width\" content=\"1141\" \/>\n\t<meta property=\"og:image:height\" content=\"633\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"InnovationM Admin\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"InnovationM Admin\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"10 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.innovationm.com\\\/blog\\\/contacts-framework-vs-addressbook-swift-3-0\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.innovationm.com\\\/blog\\\/contacts-framework-vs-addressbook-swift-3-0\\\/\"},\"author\":{\"name\":\"InnovationM Admin\",\"@id\":\"https:\\\/\\\/www.innovationm.com\\\/blog\\\/#\\\/schema\\\/person\\\/a831bf4602d69d1fa452e3de0c8862ed\"},\"headline\":\"Contacts Framework Vs AddressBook Swift 3.0\",\"datePublished\":\"2017-07-27T05:32:21+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.innovationm.com\\\/blog\\\/contacts-framework-vs-addressbook-swift-3-0\\\/\"},\"wordCount\":1198,\"commentCount\":0,\"image\":{\"@id\":\"https:\\\/\\\/www.innovationm.com\\\/blog\\\/contacts-framework-vs-addressbook-swift-3-0\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.innovationm.com\\\/blog\\\/wp-content\\\/uploads\\\/2017\\\/07\\\/Manage-Contacts_1.png\",\"articleSection\":[\"iOS\",\"Mobile\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.innovationm.com\\\/blog\\\/contacts-framework-vs-addressbook-swift-3-0\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.innovationm.com\\\/blog\\\/contacts-framework-vs-addressbook-swift-3-0\\\/\",\"url\":\"https:\\\/\\\/www.innovationm.com\\\/blog\\\/contacts-framework-vs-addressbook-swift-3-0\\\/\",\"name\":\"Contacts Framework Vs AddressBook Swift 3.0 - InnovationM - Blog\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.innovationm.com\\\/blog\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.innovationm.com\\\/blog\\\/contacts-framework-vs-addressbook-swift-3-0\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.innovationm.com\\\/blog\\\/contacts-framework-vs-addressbook-swift-3-0\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.innovationm.com\\\/blog\\\/wp-content\\\/uploads\\\/2017\\\/07\\\/Manage-Contacts_1.png\",\"datePublished\":\"2017-07-27T05:32:21+00:00\",\"author\":{\"@id\":\"https:\\\/\\\/www.innovationm.com\\\/blog\\\/#\\\/schema\\\/person\\\/a831bf4602d69d1fa452e3de0c8862ed\"},\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.innovationm.com\\\/blog\\\/contacts-framework-vs-addressbook-swift-3-0\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.innovationm.com\\\/blog\\\/contacts-framework-vs-addressbook-swift-3-0\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.innovationm.com\\\/blog\\\/contacts-framework-vs-addressbook-swift-3-0\\\/#primaryimage\",\"url\":\"https:\\\/\\\/www.innovationm.com\\\/blog\\\/wp-content\\\/uploads\\\/2017\\\/07\\\/Manage-Contacts_1.png\",\"contentUrl\":\"https:\\\/\\\/www.innovationm.com\\\/blog\\\/wp-content\\\/uploads\\\/2017\\\/07\\\/Manage-Contacts_1.png\",\"width\":1141,\"height\":633},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.innovationm.com\\\/blog\\\/contacts-framework-vs-addressbook-swift-3-0\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.innovationm.com\\\/blog\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Contacts Framework Vs AddressBook Swift 3.0\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.innovationm.com\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/www.innovationm.com\\\/blog\\\/\",\"name\":\"InnovationM - Blog\",\"description\":\"\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.innovationm.com\\\/blog\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.innovationm.com\\\/blog\\\/#\\\/schema\\\/person\\\/a831bf4602d69d1fa452e3de0c8862ed\",\"name\":\"InnovationM Admin\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/5c99d9eece9dfbc82297cf34ddd58e9fe05bb52fe66c8f6bf6c0a45bfb6d7629?s=96&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/5c99d9eece9dfbc82297cf34ddd58e9fe05bb52fe66c8f6bf6c0a45bfb6d7629?s=96&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/5c99d9eece9dfbc82297cf34ddd58e9fe05bb52fe66c8f6bf6c0a45bfb6d7629?s=96&r=g\",\"caption\":\"InnovationM Admin\"},\"sameAs\":[\"http:\\\/\\\/www.innovationm.com\\\/\"],\"url\":\"https:\\\/\\\/www.innovationm.com\\\/blog\\\/author\\\/innovationmadmin\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Contacts Framework Vs AddressBook Swift 3.0 - InnovationM - Blog","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.innovationm.com\/blog\/contacts-framework-vs-addressbook-swift-3-0\/","og_locale":"en_US","og_type":"article","og_title":"Contacts Framework Vs AddressBook Swift 3.0 - InnovationM - Blog","og_description":"Contacts Framework Contacts Framework came up \u00a0with iOS 9.0 . This framework provide Swift and Objective-C\u00a0API to\u00a0access the\u00a0user\u2019s contact information. AddressBook Framework AddressBook Framework was used in iOS 8 and earlier for access user&#8217;s contact information . Through this blog you will get to understand working with Contacts and AddressBook Framework. \u00a0So before accessing the [&hellip;]","og_url":"https:\/\/www.innovationm.com\/blog\/contacts-framework-vs-addressbook-swift-3-0\/","og_site_name":"InnovationM - Blog","article_published_time":"2017-07-27T05:32:21+00:00","og_image":[{"width":1141,"height":633,"url":"https:\/\/www.innovationm.com\/blog\/wp-content\/uploads\/2017\/07\/Manage-Contacts_1.png","type":"image\/png"}],"author":"InnovationM Admin","twitter_misc":{"Written by":"InnovationM Admin","Est. reading time":"10 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.innovationm.com\/blog\/contacts-framework-vs-addressbook-swift-3-0\/#article","isPartOf":{"@id":"https:\/\/www.innovationm.com\/blog\/contacts-framework-vs-addressbook-swift-3-0\/"},"author":{"name":"InnovationM Admin","@id":"https:\/\/www.innovationm.com\/blog\/#\/schema\/person\/a831bf4602d69d1fa452e3de0c8862ed"},"headline":"Contacts Framework Vs AddressBook Swift 3.0","datePublished":"2017-07-27T05:32:21+00:00","mainEntityOfPage":{"@id":"https:\/\/www.innovationm.com\/blog\/contacts-framework-vs-addressbook-swift-3-0\/"},"wordCount":1198,"commentCount":0,"image":{"@id":"https:\/\/www.innovationm.com\/blog\/contacts-framework-vs-addressbook-swift-3-0\/#primaryimage"},"thumbnailUrl":"https:\/\/www.innovationm.com\/blog\/wp-content\/uploads\/2017\/07\/Manage-Contacts_1.png","articleSection":["iOS","Mobile"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.innovationm.com\/blog\/contacts-framework-vs-addressbook-swift-3-0\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.innovationm.com\/blog\/contacts-framework-vs-addressbook-swift-3-0\/","url":"https:\/\/www.innovationm.com\/blog\/contacts-framework-vs-addressbook-swift-3-0\/","name":"Contacts Framework Vs AddressBook Swift 3.0 - InnovationM - Blog","isPartOf":{"@id":"https:\/\/www.innovationm.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.innovationm.com\/blog\/contacts-framework-vs-addressbook-swift-3-0\/#primaryimage"},"image":{"@id":"https:\/\/www.innovationm.com\/blog\/contacts-framework-vs-addressbook-swift-3-0\/#primaryimage"},"thumbnailUrl":"https:\/\/www.innovationm.com\/blog\/wp-content\/uploads\/2017\/07\/Manage-Contacts_1.png","datePublished":"2017-07-27T05:32:21+00:00","author":{"@id":"https:\/\/www.innovationm.com\/blog\/#\/schema\/person\/a831bf4602d69d1fa452e3de0c8862ed"},"breadcrumb":{"@id":"https:\/\/www.innovationm.com\/blog\/contacts-framework-vs-addressbook-swift-3-0\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.innovationm.com\/blog\/contacts-framework-vs-addressbook-swift-3-0\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.innovationm.com\/blog\/contacts-framework-vs-addressbook-swift-3-0\/#primaryimage","url":"https:\/\/www.innovationm.com\/blog\/wp-content\/uploads\/2017\/07\/Manage-Contacts_1.png","contentUrl":"https:\/\/www.innovationm.com\/blog\/wp-content\/uploads\/2017\/07\/Manage-Contacts_1.png","width":1141,"height":633},{"@type":"BreadcrumbList","@id":"https:\/\/www.innovationm.com\/blog\/contacts-framework-vs-addressbook-swift-3-0\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.innovationm.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Contacts Framework Vs AddressBook Swift 3.0"}]},{"@type":"WebSite","@id":"https:\/\/www.innovationm.com\/blog\/#website","url":"https:\/\/www.innovationm.com\/blog\/","name":"InnovationM - Blog","description":"","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.innovationm.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/www.innovationm.com\/blog\/#\/schema\/person\/a831bf4602d69d1fa452e3de0c8862ed","name":"InnovationM Admin","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/5c99d9eece9dfbc82297cf34ddd58e9fe05bb52fe66c8f6bf6c0a45bfb6d7629?s=96&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/5c99d9eece9dfbc82297cf34ddd58e9fe05bb52fe66c8f6bf6c0a45bfb6d7629?s=96&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/5c99d9eece9dfbc82297cf34ddd58e9fe05bb52fe66c8f6bf6c0a45bfb6d7629?s=96&r=g","caption":"InnovationM Admin"},"sameAs":["http:\/\/www.innovationm.com\/"],"url":"https:\/\/www.innovationm.com\/blog\/author\/innovationmadmin\/"}]}},"_links":{"self":[{"href":"https:\/\/www.innovationm.com\/blog\/wp-json\/wp\/v2\/posts\/3525","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.innovationm.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.innovationm.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.innovationm.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.innovationm.com\/blog\/wp-json\/wp\/v2\/comments?post=3525"}],"version-history":[{"count":0,"href":"https:\/\/www.innovationm.com\/blog\/wp-json\/wp\/v2\/posts\/3525\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.innovationm.com\/blog\/wp-json\/wp\/v2\/media\/3617"}],"wp:attachment":[{"href":"https:\/\/www.innovationm.com\/blog\/wp-json\/wp\/v2\/media?parent=3525"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.innovationm.com\/blog\/wp-json\/wp\/v2\/categories?post=3525"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.innovationm.com\/blog\/wp-json\/wp\/v2\/tags?post=3525"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}