2

I'm accessing ABAddressBook using the following code:

+ (void)connectToAddressBook {
    if(!_addressBook)
    {
        CFErrorRef error;
        _addressBook = ABAddressBookCreateWithOptions(NULL, &error);
        NSLog(@"Address book %@", _addressBook);

        if (error != nil) {
            NSLog(@"ERROR WHILE ACCESSING ADDRESS BOOK: %@", CFBridgingRelease(error));
            CFRelease(error);
        }

        if (ABAddressBookGetAuthorizationStatus() == kABAuthorizationStatusNotDetermined) {
            ABAddressBookRequestAccessWithCompletion(_addressBook, ^(bool granted, CFErrorRef error) {
                _isAccessToContactsAllowed = granted;
            });
        }
        else if (ABAddressBookGetAuthorizationStatus() == kABAuthorizationStatusAuthorized) {
            _isAccessToContactsAllowed = YES;
        }
        else {
            _isAccessToContactsAllowed = NO;
        }
    }
}

Address book opens fine, but for some reason error is not nil and logs the name of the current class:

ERROR WHILE ACCESSING ADDRESS BOOK: MyContactManager

Why is error not nil? Is my code somehow wrong? How can I detect and stop trying to access the address book in the case of a real error?

puzzler
  • 218
  • 3
  • 13
  • Check what the error says then? – Artrmz Jul 03 '15 at 07:16
  • 2
    http://stackoverflow.com/questions/19724995/my-contact-not-add-in-addressbook-in-ios-7 – Ilesh P Jul 03 '15 at 07:17
  • @Ilesh - thanks, *error works. It's strange though. That's how it was in the beginning but it broke a lot so I had to rewrite it (there was an error and the debugger got stuck while trying to log it). – puzzler Jul 03 '15 at 07:33

2 Answers2

1

Here is my fixed method thanks to feedback from Ilesh:

+ (void)connectToAddressBook {
    if(!_addressBook) {
        CFErrorRef *error = nil;
        _addressBook = ABAddressBookCreateWithOptions(NULL, error);

        // To test if error is not nil:
        //error = CFErrorCreate(NULL, CFSTR("Hello, world."), 111, NULL);

        if (error != nil) {
            NSLog(@"ERROR WHILE ACCESSING ADDRESS BOOK: %@", CFBridgingRelease(error));
            CFRelease(error);
        }
        else {
            if (ABAddressBookGetAuthorizationStatus() == kABAuthorizationStatusNotDetermined) {
                ABAddressBookRequestAccessWithCompletion(_addressBook, ^(bool granted, CFErrorRef error) {
                    _isAccessToContactsAllowed = granted;
                });
            }
            else if (ABAddressBookGetAuthorizationStatus() == kABAuthorizationStatusAuthorized) {
                _isAccessToContactsAllowed = YES;
            }
            else {
                _isAccessToContactsAllowed = NO;
            }
        }
    }
}

Edit:

It appears that my initial mistake was not assigning error to nil. Address book creation doesn't set error unless there actually is an error. So my unassigned variable pointed to some random place in memory and that's why I had random errors at my first try.

What's more, ABAddressBookCreateWithOptions will return nil if there is an error, so the correct way to do this is:

if(_addressBook) {
    // do something
}
else {
    // there is an error
}
puzzler
  • 218
  • 3
  • 13
0

Replace your whole code to this

+ (void)connectToAddressBook {
    if(!_addressBook)
    {
_addressBook = ABAddressBookCreateWithOptions(NULL, NULL);
    if (ABAddressBookGetAuthorizationStatus() == kABAuthorizationStatusNotDetermined) {
        ABAddressBookRequestAccessWithCompletion(addressBook,
                                                 ^(bool granted, CFErrorRef error) {
                                                     if (granted)
                                                      dispatch_async(dispatch_get_main_queue(), ^{
                                                        _isAccessToContactsAllowed = granted; 
                                                     });

                                                         });


    }
    else if (ABAddressBookGetAuthorizationStatus() == kABAuthorizationStatusAuthorized) {
        dispatch_async(dispatch_get_main_queue(), ^{
_isAccessToContactsAllowed = YES;

    });
    }
    else {
        UIAlertView *alert=[[UIAlertView alloc] initWithTitle:Nil message:@"You don't have permission of access contacts for access go to Setting-" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
        [alert show];
    }
}}
Kishore Suthar
  • 2,943
  • 4
  • 26
  • 44