How can I get the contact ID - ios

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 :)

Related

How to fetch contacts from AddressBook and store it in array in iOS 7?

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
}

Mysterious Loading Time of UITableView

For some reason, my app seems to take forever when I try to perform a segue. The mysterious loading time only appears, after I request permission for the AddressBook - if the Permission is already granted, there is no issue at all.
So, before actually using the Segue, i'm doing something like this:
Requesting Permission for Address Book
-(void)requestPermissionForContacts
{
ABAddressBookRef addressbook = ABAddressBookCreateWithOptions(nil, nil);
if (ABAddressBookGetAuthorizationStatus() == kABAuthorizationStatusNotDetermined)
{
ABAddressBookRequestAccessWithCompletion(addressbook, ^(bool granted, CFErrorRef error) {
if (granted)
{
NSLog(#"granted");
[self didGrantPermissions];
} else{
NSLog(#"denied");
[self didNotGrantPermission];
}
});
}
else if (ABAddressBookGetAuthorizationStatus() == kABAuthorizationStatusAuthorized)
{
[self didGrantPermissions];
} else {
[self didNotGrantPermission];
}
CFRelease(addressbook);
}
Whatever they user clicks:
-(void)didGrantPermissions
{
[self performSegueWithIdentifier:#"addressBook" sender:nil];
}
-(void)didNotGrantPermission
{
[[[UIAlertView alloc] initWithTitle:#"Address Book" message:#"To access this feature, please allow us to access your Address Book" delegate:nil cancelButtonTitle:#"Ok" otherButtonTitles:nil, nil] show];
}
And after that,
prepareForSegue
if ([segue.identifier isEqualToString:#"addressBook"])
{
CWAddressBookViewController *abvc = segue.destinationViewController;
abvc.delegate = self;
abvc.addressType = self.addressType;
}
If it is the first time, the App is accessing this view (so, if its still asking for permission) it takes quite a while (20sec!) until -(void)viewDidLoad is being called on CWAddressBookViewControlller
If the permission is already granted, it is performing the segue as expected in the blink of an eye.
Any idea what im doing wrong here?

Spotify EXC_BAD_EXE while second time tap on Login Button after dismiss LoginViewController

Hi i Intigrate SpotifyLib CocoaLibSpotify iOS Library 17-20-26-630 into my Project. I open its SPLoginViewController using Bellow Method:-
-(void)OpenSpotify
{
NSError *error = nil;
[SPSession initializeSharedSessionWithApplicationKey:[NSData dataWithBytes:&g_appkey length:g_appkey_size]
userAgent:#"com.mycomp.spotify"
loadingPolicy:SPAsyncLoadingImmediate
error:&error];
if (error != nil) {
NSLog(#"CocoaLibSpotify init failed: %#", error);
abort();
}
[[SPSession sharedSession] setDelegate:self];
[self performSelector:#selector(showLogin) withObject:nil afterDelay:0.0];
}
-(void)showLogin
{
SPLoginViewController *controller = [SPLoginViewController loginControllerForSession:[SPSession sharedSession]];
controller.allowsCancel = YES;
//controller.view.frame=;
[self presentViewController:controller animated:YES completion:nil];
}
At First time that Appear Spotify Login Screen. After that I tap On Cancel Button, and Try to open again login screen then i got crash EXC_BAD_EXE at this line. sp_error createErrorCode = sp_session_create(&config, &_session);
UPDATE
I Found exet where is got BAD_EXC
in this method
+(void)dispatchToLibSpotifyThread:(dispatch_block_t)block waitUntilDone:(BOOL)wait {
NSLock *waitingLock = nil;
if (wait) waitingLock = [NSLock new];
// Make sure we only queue one thing at a time, and only
// when the runloop is ready for it.
[runloopReadyLock lockWhenCondition:1];
CFRunLoopPerformBlock(libspotify_runloop, kCFRunLoopDefaultMode, ^() {
[waitingLock lock];
if (block) { #autoreleasepool { block(); } }
[waitingLock unlock];
});
if (CFRunLoopIsWaiting(libspotify_runloop)) {
CFRunLoopSourceSignal(libspotify_runloop_source);
CFRunLoopWakeUp(libspotify_runloop);
}
[runloopReadyLock unlock]; // at hear when my debug poin reach after pass this i got bad_exc
if (wait) {
[waitingLock lock];
[waitingLock unlock];
}
}
after doing lots of search i got Solution i check that whether the session already exists then i put if condition like:-
-(void)OpenSpotify
{
SPSession *session = [SPSession sharedSession];
if (!session) {
NSError *error = nil;
[SPSession initializeSharedSessionWithApplicationKey:[NSData dataWithBytes:&g_appkey length:g_appkey_size]
userAgent:#"com.mycomp.spotify"
loadingPolicy:SPAsyncLoadingImmediate
error:&error];
if (error != nil) {
NSLog(#"CocoaLibSpotify init failed: %#", error);
abort();
}
[[SPSession sharedSession] setDelegate:self];
}
[self performSelector:#selector(showLogin) withObject:nil afterDelay:0.0];
}
-(void)showLogin
{
SPLoginViewController *controller = [SPLoginViewController loginControllerForSession:[SPSession sharedSession]];
controller.allowsCancel = YES;
[self presentViewController:controller animated:YES completion:nil];
}
Now no crash and working fine.

IOS - Get Contact phone use to Address Book

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];

Crash while fetching the contacts from the address book database for the iOS version 6.1.3?

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];
}
}

Resources