ABAuthorizationStatus status = ABAddressBookGetAuthorizationStatus();
if (status == kABAuthorizationStatusNotDetermined) {
NSLog(#"未知");
ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL,NULL);
ABAddressBookRequestAccessWithCompletion(addressBook, ^(bool granted, CFErrorRef error) {
if (granted) {
NSLog(#"ok");
} else {
NSLog(#"nonono,always here");
}
CFRelease(addressBook);
});
}
If I create a new project, this code will compile.
But in my current project no alert is given and the build fails with the following error
kABAuthorizationStatusNotDetermined state and granted = nil
I can't tell what the variable "status" is from your code. You can try with following code.
if (ABAddressBookGetAuthorizationStatus() == kABAuthorizationStatusNotDetermined) {
ABAddressBookRef addressBookRef = ABAddressBookCreateWithOptions(nil, nil);
ABAddressBookRequestAccessWithCompletion(addressBookRef, ^(bool granted, CFErrorRef error) {
if (granted) {
//You've got contacts permission
} else {
//User denied to give permission
}
});
}
Related
I have following snippets of code that fetches contacts by using block:
if (&ABAddressBookCreateWithOptions != NULL) {
CFErrorRef error = nil;
addressBook = ABAddressBookCreateWithOptions(NULL, &error);
ABAddressBookRequestAccessWithCompletion(addressBook, ^(bool granted, CFErrorRef error) {
dispatch_sync(dispatch_get_main_queue(), ^{
if (error) {
//...
} else if (!granted) {
//...
} else {
// access granted
//...
}
});
});
It works fine on both 7.1.2 and 8.1.3 versions.
However when I try to change dispatch_get_main_queue to dispatch_get_global_queue(QOS_CLASS_BACKGROUND, 0) it works on 8.1.3 but crashes on 7.1.2
if (&ABAddressBookCreateWithOptions != NULL) {
CFErrorRef error = nil;
addressBook = ABAddressBookCreateWithOptions(NULL, &error);
ABAddressBookRequestAccessWithCompletion(addressBook, ^(bool granted, CFErrorRef error) {
dispatch_sync(dispatch_get_global_queue(QOS_CLASS_BACKGROUND, 0), ^{ // BAD ACCESS
if (error) {
//...
} else if (!granted) {
//...
} else {
// access granted
//...
}
});
});
The QOS_CLASS_ identifiers were introduced in iOS 8. You need to use the DISPATCH_QUEUE_PRIORITY_ identifiers if you want to support iOS 7.
I have a problem with getting the contact ID from the address book.
My .m file:
-(IBAction)test:(id)sender
{
ABPeoplePickerNavigationController* picker = [[ABPeoplePickerNavigationController alloc] init];
picker.peoplePickerDelegate = self;
[self presentViewController:picker animated:YES completion:nil];
}
-(void)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker didSelectPerson:(ABRecordRef)person
{
[peoplePicker dismissViewControllerAnimated:YES completion:nil];
ABRecordID recordID = ABRecordGetRecordID(person);
label.text = [NSString stringWithFormat:#"%d", recordID];
}
-(void)peoplePickerNavigationControllerDidCancel:(ABPeoplePickerNavigationController *)peoplePicker
{
[peoplePicker dismissViewControllerAnimated:YES completion:nil];
}
I imported the AddressBook and the AddressBookUI into the .h file.
It works all but I get the wrong ID.
Everytime I only get the ID -1 and that stands for error.
Hope you can help me.
Thanks a lot,
Christian
In iOS 8, it no longer automatically requests permission for the address book when just showing the people picker. (The idea is that is that the picker, alone, is not really giving the app access to your contacts, so no permission should be required. It offers low-friction UI when app isn't really getting the contact details.)
But, in your case, you really are trying to programmatically retrieve information about the contact. For that, you do need permission. So, prior to presenting the picker, you might want to ask permission to the address book:
ABAuthorizationStatus status = ABAddressBookGetAuthorizationStatus();
if ((status == kABAuthorizationStatusDenied || status == kABAuthorizationStatusRestricted)) {
NSLog(#"User previously denied permission; show error message that they must go to settings and give this app permission");
return;
} else if (status == kABAuthorizationStatusNotDetermined) {
CFErrorRef error;
ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, &error);
if (!addressBook) {
NSLog(#"unable to open address book: %#", CFBridgingRelease(error));
return;
}
ABAddressBookRequestAccessWithCompletion(addressBook, ^(bool granted, CFErrorRef error) {
if (granted) {
NSLog(#"OK");
} else {
NSLog(#"Not ok");
}
CFRelease(addressBook);
});
}
Here my solution how to get the ID of a contact:
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
ABAuthorizationStatus status = ABAddressBookGetAuthorizationStatus();
if ((status == kABAuthorizationStatusDenied || status == kABAuthorizationStatusRestricted)) {
NSLog(#"User previously denied permission; show error message that they must go to settings and give this app permission");
return;
} else if (status == kABAuthorizationStatusNotDetermined) {
CFErrorRef error;
ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, &error);
if (!addressBook) {
NSLog(#"unable to open address book: %#", CFBridgingRelease(error));
return;
}
ABAddressBookRequestAccessWithCompletion(addressBook, ^(bool granted, CFErrorRef error) {
if (granted) {
NSLog(#"OK");
} else {
NSLog(#"Not ok");
}
CFRelease(addressBook);
});
}
ABPeoplePickerNavigationController* picker = [[ABPeoplePickerNavigationController alloc] init];
picker.peoplePickerDelegate = self;
[self presentViewController:picker animated:YES completion:nil];
}
-(void)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker didSelectPerson:(ABRecordRef)person
{
[peoplePicker dismissViewControllerAnimated:YES completion:nil];
ABRecordID recordID = ABRecordGetRecordID(person);
NSLog([NSString stringWithFormat:#"%#"], recordID);
}
Thanks to Rob who helped me out :)
NSMutableArray *arrContacts=[[NSMutableArray alloc]init];
CFErrorRef *error = nil;
ABAddressBookRef addressbook = ABAddressBookCreateWithOptions(NULL, error);
__block BOOL accessGranted = NO;
if (ABAddressBookRequestAccessWithCompletion != NULL) { // we are used on the 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(addressbook, ^(bool granted, CFErrorRef error) {
accessGranted = granted;
dispatch_semaphore_signal(sema);
});
dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
}
else { // we're on iOS 5 or older
accessGranted = YES;
}
if (accessGranted)
{
}
Above code working fine in simulator but when i run the application in Iphone 5c it is not asking me for permission and i'm not able to get phone numbers from device addressbook.
help me to solve this issue.
Thanks in advance.
call this line in your viewDidLoad method
ABAddressBookRef addressBookRef = ABAddressBookCreateWithOptions(nil, nil);
if (ABAddressBookGetAuthorizationStatus() == kABAuthorizationStatusNotDetermined) {
ABAddressBookRequestAccessWithCompletion(addressBookRef, ^(bool granted, CFErrorRef error) {
if (granted) {
// If the app is authorized to access the first time then add the contact
} else {
// Show an alert here if user denies access telling that the contact cannot be added because you didn't allow it to access the contacts
}
});
}
else if (ABAddressBookGetAuthorizationStatus() == kABAuthorizationStatusAuthorized) {
// If the user user has earlier provided the access, then add the contact
}
else {
// If the user user has NOT earlier provided the access, create an alert to tell the user to go to Settings app and allow access
}
I am trying to fetch contacts from address book and then to store it in an array.I am not able to do this.I checked various posts on stack overflow and i am writing the same code but not able to do?
CFErrorRef error = NULL;
ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, &error);
if (addressBook != nil) {
NSLog(#"Succesful.");
allContacts = (__bridge_transfer NSArray *)ABAddressBookCopyArrayOfAllPeople(addressBook);
NSLog(#"allContacts.count = %d",[allContacts count]);} allContact count is always zero
#property (nonatomic, assign) ABAddressBookRef addressBook;
// Check user permission
-(void)requestAddressBookAccess
{
ViewController * __weak weakSelf = self;
ABAddressBookRequestAccessWithCompletion(self.addressBook, ^(bool granted, CFErrorRef error)
{
if (granted)
{
dispatch_async(dispatch_get_main_queue(), ^{
[weakSelf accessGrantedForAddressBook];
});
}
else{
}
});
}
// Get all the contect
-(void)accessGrantedForAddressBook{
ABAddressBookRef addressBook = ABAddressBookCreate();
CFArrayRef people = ABAddressBookCopyArrayOfAllPeople(addressBook);
CFMutableArrayRef peopleMutable = CFArrayCreateMutableCopy(
kCFAllocatorDefault,
CFArrayGetCount(people),
people
);
NSMutableArray *allNames = (__bridge NSMutableArray*)peopleMutable;
}
That might be possible because you are not Requesting Access to Contacts from user.
Just add this to your code.
#import <AddressBookUI/AddressBookUI.h>
// Request authorization to Address Book
ABAddressBookRef addressBookRef = ABAddressBookCreateWithOptions(NULL, NULL);
if (ABAddressBookGetAuthorizationStatus() == kABAuthorizationStatusNotDetermined) {
ABAddressBookRequestAccessWithCompletion(addressBookRef, ^(bool granted, CFErrorRef error) {
if (granted) {
// First time access has been granted, add the contact
[self _addContactToAddressBook];
} else {
// User denied access
// Display an alert telling user the contact could not be added
}
});
}
else if (ABAddressBookGetAuthorizationStatus() == kABAuthorizationStatusAuthorized) {
// The user has previously given access, add the contact
[self _addContactToAddressBook];
}
else {
// The user has previously denied access
// Send an alert telling user to change privacy setting in settings app
}
I have developed the application to fetch the contacts from the address book database. For this the implemented code is code fine for the iOS version 6.0, but it crashes on iOS 6.1.3.
The code which I have implemented to fetch the contacts from the address book database:
ABAddressBookRef addressBook;
if ([self isABAddressBookCreateWithOptionsAvailable]) {
// iOS 6
CFErrorRef error = nil;
addressBook = ABAddressBookCreateWithOptions(NULL,&error);
ABAddressBookRequestAccessWithCompletion(addressBook, ^(bool granted, CFErrorRef error) { });
ABAddressBookRevert(addressBook);
} else {
// iOS 4/5
addressBook = ABAddressBookCreate();
}
-(BOOL)isABAddressBookCreateWithOptionsAvailable
{
return &ABAddressBookCreateWithOptions != NULL;
}
Please help me with this.
i'm not sure that this code will crash or not but i think this should be run in iOS 6.1.3
-(IBAction)btnShowContactClicked {
//ABAddressBookRef addressBook = ABAddressBookCreate();
CFErrorRef *aberror = NULL;
addressBook = ABAddressBookCreateWithOptions(NULL, aberror);
__block BOOL accessGranted = NO;
if (ABAddressBookRequestAccessWithCompletion != NULL) { // we're on iOS 6
dispatch_semaphore_t sema = dispatch_semaphore_create(0);
ABAddressBookRequestAccessWithCompletion(addressBook, ^(bool granted, CFErrorRef error) {
accessGranted = granted;
dispatch_semaphore_signal(sema);
});
dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
dispatch_release(sema);
}
else { // we're on iOS 5 or older
accessGranted = YES;
}
if (accessGranted) {
ABPeoplePickerNavigationController *picker = [[ABPeoplePickerNavigationController alloc] init];
picker.peoplePickerDelegate = self;
[self presentViewController:picker animated:YES completion:nil];
// //[self.navigationController presentModalViewController:picker animated:YES];
[picker release];
}
}