I want to ask that how I can detect whether my AddressBook was first accessed by an app on ios6.0. I have learnt that no matter an app was reinstalled or not , the system only thinks that the first installation an first launch is the first time an app launched. the question is that I want to remind an user to allow the app access AddressBook with an UIAlertView,but this alertview will appear shortly after the system's alertview .How can I avoid this condition. Any help will be greatly appreciated.
3 Answers
You should basically ignore ABAddressBookRequestAccessWithCompletion
. It is useless. If you want to know whether you have access to the database, call ABAddressBookGetAuthorizationStatus()
.
Further Discussion
ABAddressBookRequestAccessWithCompletion
is said by the docs to request address book access from the user. But it doesn't. I will now demonstrate that ABAddressBookRequestAccessWithCompletion
is useless. There are two situations:
(1) If this is a completely unknown new app, ABAddressBookRequestAccessWithCompletion
is otiose: access will be requested from the user automatically when the app tries to access the address book, so there is no need for ABAddressBookRequestAccessWithCompletion
.
(2) If the user has either denied or granted access, ABAddressBookRequestAccessWithCompletion
is a no-op! Calling it does nothing; it does not put up the access request alert!
So ABAddressBookRequestAccessWithCompletion
is just a bug and should be ignored.
A Major Correction
EDIT In iOS 6.1, this behavior appears to have changed. (I am assuming that my tests on iOS 6.0 were valid, but I have every reason to believe they were.) Now, however, in iOS 6.1, ABAddressBookCreateWithOptions
never causes the authorization alert to appear. The only way to make it appear is with ABAddressBookRequestAccessWithCompletion
! Thus this function is now essential; if ABAddressBookGetAuthorizationStatus
that access is undetermined, you must call ABAddressBookRequestAccessWithCompletion
or you won't get access.

- 515,959
- 87
- 875
- 1,141
I have solved it by this way.
__block BOOL accessGranted;
- (IBAction)accessAddressBook:(id)sender {
CFErrorRef error;
ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL,&error);
ABAddressBookRequestAccessWithCompletion(addressBook, ^(bool granted, CFErrorRef error) {
// accessGranted = granted;
if (!accessGranted && !granted) {
UIAlertView * alertView = [[UIAlertView alloc]initWithTitle:@"Deny Access" message:@"Deny" delegate:self cancelButtonTitle:nil otherButtonTitles:@"cancel", nil];
[alertView show];
[alertView release];
}
});
}
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
if ([alertView.message isEqualToString:@"use contact"] || alertView.message == @"use contact") {
accessGranted = YES;
}
}
The system already shows an alert when you call ABAddressBookRequestAccessWithCompletion() just augment the system app with your own string.
You should have in your InfoPlist.strings:
"NSContactsUsageDescription" = "Tap 'OK' or this app is useless.";

- 4,195
- 1
- 19
- 17