Question

I have a view controller where I am trying to access the user's address book on viewDidLoad. When the user lands on the view controller, I want to have an alert window popup asking them if the app can access the contacts in their address book, and then they can select "Ok" or "Don't Allow."

What's weird is I was under the impression that my code was setup correctly to do this. However, whenever I run the app on my iPhone and visit this view controller it doesn't even ask me for permission and just automatically accesses my contacts. I have even tried deleting the app and all of it's data from my iPhone, and then re-running in xcode and on my iPhone.

I'm not sure if it's a glitch because I'm the developer, or if there's something wrong with my code.

Here is the code I use to access the address book in viewDidLoad:

- (void)viewDidLoad {

[super viewDidLoad];

// Do any additional setup after loading the view.

//Asks for access to Address Book.

ABAddressBookRef m_addressbook =  ABAddressBookCreateWithOptions(NULL, NULL);


ABAddressBookCopyArrayOfAllPeople(m_addressbook);


__block BOOL accessGranted = NO;
if (ABAddressBookRequestAccessWithCompletion != NULL) { // we're on iOS 6
    dispatch_semaphore_t sema = dispatch_semaphore_create(0);
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        @autoreleasepool {

            // Write your code here...
            // Fetch data from SQLite DB
        }
    });

    ABAddressBookRequestAccessWithCompletion(m_addressbook, ^(bool granted, CFErrorRef error)

    {
        accessGranted = granted;

        NSLog(@"Has access been granted?: %hhd", accessGranted);
        NSLog(@"Has there been an error? %@", error);


        dispatch_semaphore_signal(sema);
    });
    dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
}
else { // we're on iOS 5 or older
    accessGranted = YES;

    NSLog(@"Address book access has been granted.");
}

if (accessGranted) {


    NSArray *allContacts = (__bridge_transfer NSArray
                            *)ABAddressBookCopyArrayOfAllPeople(m_addressbook);

And then basically if access is granted I start loading all of the names and phone numbers into the view controller's UITableView.

I really need to figure out why this is behaving this way and would also like to add an alert view that asks the user if they would like to allow access to the address book contacts.

Is it not actually asking for access because my code is wrong? Because it knows I'm the developer? Like I said I am running this after deleting the app and all of it's data from my iPhone.

UPDATE: I am using iOS 7.0.4 if that makes a difference.

Was it helpful?

Solution

One mistake I see in your code is that you have this:

if (ABAddressBookRequestAccessWithCompletion != NULL) {

This should be:

if (ABAddressBookGetAuthorizationStatus() == kABAuthorizationStatusNotDetermined) {

The problem with your original code is that ABAddressBookRequestAccessWithCompletion is not anything: it requires parameters, like you use later on in the same if statement. I am surprised you are not getting an error from Xcode. ABAddressBookGetAuthorizationStatus was new in iOS 6.

Also, you are supposed to create the Address Book Ref after you get permission, not before.

It is also possible that because the app was on your iPhone at some point, it remembers that you gave permission to the app to use your contacts. In the iOS simulator, there is a Reset Content and Settings option. This makes the simulator forget any permission settings you gave your app. I find it unlikely that you want to reset your iPhone, correct?

OTHER TIPS

I finally figured this out. Deleting an app and "all of it's data" is a misleading dialogue provided by your iPhone. In regards to testing with privacy settings, you have to go to Settings > General > Reset > Reset Location & Privacy. By doing this, you get a truly "fresh" environment that will allow you to test your "privacy access" code. Keep in mind that this will delete your location and privacy settings that you have set for all of the other apps you use.

Use this code.....

if (ABAddressBookGetAuthorizationStatus == ABAuthorizationStatusNotDetermined){

instead of.....

 if (ABAddressBookRequestAccessWithCompletion != NULL) {
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top