2

According to the documentation with iOS6 an address book should be created using ABAddressBookCreateWithOptions.

It also says if the caller does not have access to the db then this method will return null.

However access is requested by calling ABAddressBookRequestAccessWithCompletion, which takes an ABAddressBookRef as a parameter.

So according to the documentation you can't get an ABAddressBookRef in the first place if you don't have access, but to get access you have to have an ABAddressBookRef to pass as a parameter.

Eh. Catch 22? How do you create an ABAddressBookRef then?

Been googling for some example/tutorial code for this but haven't found any.

TIA

Gruntcakes
  • 37,738
  • 44
  • 184
  • 378

2 Answers2

4

I use code like this:

if (ABAddressBookCreateWithOptions) {
    _book = ABAddressBookCreateWithOptions(NULL, NULL);
    if (ABAddressBookGetAuthorizationStatus() == kABAuthorizationStatusNotDetermined) {
        ABAddressBookRequestAccessWithCompletion(_book, ^(bool granted, CFErrorRef error) {
            dispatch_async(dispatch_get_main_queue(), ^{
                if (granted && !error) {
                    ABAddressBookRevert(_book);
                }
            });
        });
    }
} else {
    _book = ABAddressBookCreate();
}

where _book is my ABAddressBookRef.

If my app has been denied access then _book will be NULL and you can't access the address book.

rmaddy
  • 314,917
  • 42
  • 532
  • 579
  • Thanks, so if the first time you run this code then _book should be null as access has not yet been granted, so when you then call ABAddressBookRequestAccessWithCompletion to prompt for access, passing null what happens next? How can you subsequently use _book if its null? – Gruntcakes Oct 24 '12 at 18:19
  • 4
    The first time you run, the authorization status is "not determined". So the call to `ABAddressBookCreateWithOptions` returns a non-nil reference but it references an empty address book. When you then call `ABAddressBookRequestAccessWithCompletion`, if the user granted access, the call to `ABAddressBookRevert` updates the `_book` reference with a non-empty address book. So `_book` is only NULL when your app has already been denied - which can't happen the first time your app runs. – rmaddy Oct 24 '12 at 18:23
0

See my answer here:

https://stackoverflow.com/a/13671852/341994

ABAddressBookRequestAccessWithCompletion is useless and should be ignored.

  • If you need to know the authorization status, call ABAddressBookGetAuthorizationStatus.

  • If the authorization is undetermined (the user has never run this app), just attempt to access the database. This will cause the authorization alert to appear.

  • If the user has authorized or denied access, ABAddressBookRequestAccessWithCompletion does nothing of any value so there's no point calling it.

Community
  • 1
  • 1
matt
  • 515,959
  • 87
  • 875
  • 1,141
  • Particularly annoying: If a user initially denies access on ABAddressBookRequestAccessWithCompletion, then you can't call it again as you'll get NULL for the AB parameter required. So you can't ask for permission once it's been denied. – n13 Dec 09 '12 at 04:16
  • according to your update in that answer, this no longer is correct. –  Oct 08 '13 at 10:05