-3

I develop application on iOS 6 that need access to AddressBook, I'm using following code:

NSMutableArray *contacts = [[NSMutableArray alloc]init];
CFErrorRef *error = nil;
ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, error);
if (error)
{NSLog(@"ERROR!!!");}
NSArray *arrayOfPeople = (__bridge_transfer NSArray*)ABAddressBookCopyArrayOfAllPeople(addressBook);

but on real device arrayOfPeople is empty...Why is this happening? P.S. All accesses to AddressBook are granted

rmaddy
  • 314,917
  • 42
  • 532
  • 579
InViZz
  • 109
  • 1
  • 4
  • 12

1 Answers1

8

First, here's a rewrite of your code in proper form as a starting place.

CFErrorRef error = nil; // no asterisk
ABAddressBookRef addressBook = 
    ABAddressBookCreateWithOptions(NULL, &error); // indirection
if (!addressBook) // test the result, not the error
{
    NSLog(@"ERROR!!!");
    return; // bail
}
CFArrayRef arrayOfPeople = ABAddressBookCopyArrayOfAllPeople(addressBook);
NSLog(@"%@", arrayOfPeople); // let's see how we did

Second, here's the actual cause of your problem: you've no access. At some point you need to have called ABAddressBookRequestAccessWithCompletion to ensure access. Note that this call is asynchronous, so you will need to get the array of people from a separate call, or in the completion handler.

The docs seem to imply that you'll get NULL if there is no access, but this is not the case if access is undetermined. Instead, you get a useless empty read-only address database. Thus the only way to be sure you have access is to check explicitly with ABAddressBookGetAuthorizationStatus, and the only to way to get the request for access alert to appear is to call ABAddressBookRequestAccessWithCompletion.

This might be new iOS 6.1 behavior. It is certainly not how I remember things from iOS 6.0.

This same issue doesn't arise in the Simulator because you are granted access automatically (rather unrealistic - another good reason to test only on the device for this sort of thing).

matt
  • 515,959
  • 87
  • 875
  • 1,141
  • At least log the `error` variable instead of just the word "ERROR!!!". – rmaddy May 16 '13 at 03:09
  • result of NSLog(@"People: %@", arrayOfPeople) is People: ( ) – InViZz May 16 '13 at 04:48
  • Because you have no access. You've never called `ABAddressBookRequestAccessWithCompletion`. – matt May 16 '13 at 15:40
  • funny that this question was closed. I'm having the same problem.. I believe(just a bit different perhaps) I already granted access on my phone, and When I use `NSLog(@"%@", addressBookRef);` it prints to the console, some useless address in this form: `` Any way to, for lack of a better word, "deque" the access? – Chisx Jan 13 '14 at 00:03
  • Nevermind, scratch that, different question. Does the **array** variable that "catches", you might say, the address book have to be of type `CFArrayRef`? – Chisx Jan 13 '14 at 00:13