I've a device phone run ios 6.0.1, and i want get all contact in my device. I tried on iphone use to IOS 5.1, 6.1.3 and it's work ok. Unfortunately, when it's run ios 6.0.1, data is null
This is my code:
if ([[[UIDevice currentDevice] systemVersion] floatValue] > 5.2) {
ABAddressBookRef addressBookRef = ABAddressBookCreateWithOptions(NULL, NULL);
if (ABAddressBookGetAuthorizationStatus() == kABAuthorizationStatusNotDetermined)
{
ABAddressBookRequestAccessWithCompletion(addressBookRef,
^(bool granted, CFErrorRef error) {
if (granted)
[self loadContact];
});
}
else if (ABAddressBookGetAuthorizationStatus() == kABAuthorizationStatusAuthorized)
{
[self loadContact];
}
}
else
{
[self loadContact];
}
-(void) loadContact {
ABAddressBookRef addressBooks = ABAddressBookCreate();
allPeople = (__bridge NSArray *)(ABAddressBookCopyArrayOfAllPeople(addressBooks));
peopleCount = ABAddressBookGetPersonCount(addressBooks); }
I don't know, why it doesn't work on ios 6.0.1
I found this link, and do it, but my device have not data.
Can you help me this problem?
The biggest problem in your code is that you need to pass reference "addressBookRef" to your "loadContact" method. "ABAddressBookCreate" won't work for iOS6 - you need to use the one created by ABAddressBookRequestAccessWithCompletion.
Btw. Instead of checking for iOS version better use that to determinate if you need to ask for permissions. Here is a code I'm using - feel free to use it:
-(BOOL)isABAddressBookCreateWithOptionsAvailable {
return &ABAddressBookCreateWithOptions != NULL;
}
- (void) importContactsFromAddressBook
{
ABAddressBookRef addressBook;
if ([self isABAddressBookCreateWithOptionsAvailable]) {
CFErrorRef error = nil;
addressBook = ABAddressBookCreateWithOptions(NULL,&error);
ABAddressBookRequestAccessWithCompletion(addressBook, ^(bool granted, CFErrorRef error) {
// callback can occur in background, address book must be accessed on thread it was created on
if (error) {
[self.delegate addressBookHelperError:self];
} else if (!granted) {
[self.delegate addressBookHelperDeniedAcess:self];
AddressBookUpdated(addressBook, nil, self);
} else {
// access granted
AddressBookUpdated(addressBook, nil, self);
CFRelease(addressBook);
}
});
} else {
// iOS 4/5
addressBook = ABAddressBookCreate();
AddressBookUpdated(addressBook, NULL, self);
CFRelease(addressBook);
}
}
void AddressBookUpdated(ABAddressBookRef addressBook, CFDictionaryRef info, void *context)
{
NSMutableArray* addressBookContacts = [NSMutableArray array];
//import from address book
CFArrayRef allPeople = ABAddressBookCopyArrayOfAllPeople( addressBook );
CFIndex nPeople = ABAddressBookGetPersonCount( addressBook );
[helper.delegate performSelectorOnMainThread:#selector(didLoadList:)
withObject:[NSNumber numberWithInt:nPeople]
waitUntilDone:YES];
if(allPeople) CFRelease(allPeople);
[helper.delegate performSelectorOnMainThread:#selector(didComplete:)
withObject:addressBookContacts
waitUntilDone:YES];
}
I have those functions encapsulated into class and delegate is:
#protocol ContactImporterProgressViewDelegate <NSObject>
- (void) didLoadList:(NSNumber*) totalItems;
- (void) updateProgress:(NSNumber*) progress;
- (void) didComplete:(NSArray*) contactsImported;
#end
#property (nonatomic, assign) NSObject <ContactImporterProgressViewDelegate>* delegate;
To use it I would suggest to call it on another thread to don't block UI and show progress (it takes a while when you have 5000 entries):
ContactImporter* importer = [[ContactImporter alloc] init];
importer.delegate = self;
NSOperationQueue *queue = [[[NSOperationQueue alloc] init] autorelease];
NSInvocationOperation *oper = [[[NSInvocationOperation alloc] initWithTarget:importer
selector:#selector(importContactsFromAddressBook)
object:nil] autorelease];
[queue addOperation:oper];
[importer release];
Related
My question is very simple: how come the code below works when I use the simulator, but not the device?
I've used two iPad Airs on a deployment target of 8.2 and 8.4, and an iPad Mini (don't know which one, but relatively new) on 8.2, and none of them are able to add a group.
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
ABAddressBookRef addressBook;
bool didSave;
CFErrorRef error = NULL;
addressBook = ABAddressBookCreateWithOptions(NULL, &error);
// If you get some error when trying to add a contact, make sure it's not a permission issue
ABAddressBookRequestAccessWithCompletion(addressBook, ^(bool granted, CFErrorRef error) {
if (granted) {
[self createNewGroup:#"New Group"];
}
});
// [self createNewGroup:#"New Group"];
}
-(void)createNewGroup:(NSString *)groupName
{
CFErrorRef error = NULL;
bool didSet, didAdd, didSave;
ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, &error);
if (error) {
NSLog(#"Error: %#", error);
}
ABRecordRef newGroup = ABGroupCreate();
didSet = ABRecordSetValue(newGroup, kABGroupNameProperty, (__bridge CFTypeRef)(groupName), &error);
if (!didSet) { NSLog(#"Unresolved error while setting group: %#", error); }
didAdd = ABAddressBookAddRecord(addressBook, newGroup, &error);
if (!didAdd) { NSLog(#"Unresolved error while adding group: %#", error); };
didSave = ABAddressBookSave(addressBook, &error);
if (!didSave) { NSLog(#"Unresolved error while saving group: %#", error); };
ABRecordID groupId = ABRecordGetRecordID(newGroup);
// CFRelease(addressBook);
// CFRelease(newGroup);
// CFRelease(error);
}
You should do:
#if TARGET_IPHONE_SIMULATOR
[self createNewGroup:#"New Group"];
#endif
Already asked in: What #defines are set up by Xcode when compiling for iPhone
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];
}
}