Thursday, November 1, 2012

ios 6 -- Access Address Book (Contacts)


In iOS 6, we need to get the permission to access user's contacts.(in ios 5 or below, it is no need to ask for permission).


Here is the code to access contacts works both iOS 6 and iOS 5 or below:



-(void)getAddressBookPermission
{
    
    if (ABAddressBookRequestAccessWithCompletion) { // if in iOS 6
  
    // Request authorization to Address Book
    ABAddressBookRef addressBookRef = ABAddressBookCreateWithOptions(NULL, NULL);
    
    if (ABAddressBookGetAuthorizationStatus() == kABAuthorizationStatusNotDetermined) {
        ABAddressBookRequestAccessWithCompletion(addressBookRef, ^(bool granted, CFErrorRef error) {
            // First time access has been granted, add the contact
        });
    }
    else if (ABAddressBookGetAuthorizationStatus() == kABAuthorizationStatusAuthorized) {
        // The user has previously given access, add the contact
    }
     else {
        // The user has previously denied access
        // Send an alert telling user to change privacy setting in settings app
    }
    }
    else{ // if not in iOS 6
     // just get the contacts directly
    }
}


This is the very useful tips for testing the Contacts pop up in iOS 6. 

Generally, the VERY FIRST time your app runs is the only time the ABAuthorizationStatus iskABAuthorizationStatusNotDetermined.  Then and only then will ABAddressBookRequestAccessWithCompletion() display the authorization prompt to the user.  Also, while in this state, ABAddressBookCreateWithOptions() DOES return a non-NULL ABAddressBookRef.  So there's no use in calling ABAddressBookRequestAccessWithCompletion() unless you're in this state.

If the state is kABAuthorizationStatusDenied or kABAuthorizationStatusRestricted, the only thing to do is let the user know that your app can't get access to the contacts, and if he/she WANTS your app to have access, he/she must go to Settings->Privacy->Contacts and OK the app.  (Initially, I thought I could, in this case, useABAddressBookRequestAccessWithCompletion() to ask the user for permission.  It would have been a lot more convenient for him/her.)

For testing purposes, there IS a way to get back to kABAuthorizationStatusNotDetermined.  You go to Settings->General->Reset and reset Contacts&Location.  This resets the contact and location permission settings for all apps.

Apple, if you're out there, the AddressBook docs SCREAM for more complete documentation!  This new permission stuff is quite unclear.  Even worse is any sort of docmentation about AB "sources".  A "source" is never even defined.  I figured them out but at great time-expense.  For example, nowhere is it stated that if you have multiple sources with the same contact, you'll get both contact records separately.  (One COULD assume that the system would take care of syncing contacts from multiple sources, but no.)  It's up the contact-displaying app to merge these contacts in a coherent UI.  It wouldn't so bad that this is a LOT of work if only it were documented somewhere. 

2 comments:

  1. I Could nor agree more. There is a ton of bad address book code out there because developers are guessing how this stuff works. Better documentation and current examples would save endless hours of debugging.

    ReplyDelete
  2. Hey! Thanks for this blog. It's really worth reading it.

    ReplyDelete