This works fine when I select contacts that have multiple phone numbers, and pick one of their phone numbers, recipientAddress is set to the selected phone number. But when I select email addresses from contacts having multiple email addresses, the ABMultiValueIdentifier is zero, and it translates into an index of zero, which is always the last email in the contact, regardless of which I selected.
I must be doing something embarrassingly wrong and easy to find, so please make yourself look great by exposing my foolishness.
- (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker shouldContinueAfterSelectingPerson:(ABRecordRef)person property:(ABPropertyID)property identifier:(ABMultiValueIdentifier)identifier
{
#try {
[eta addRecipient: person : property: identifier];
}
#catch (NSException *exception) {
errExcLog(exception);
}
return NO;
}
- (void) addRecipient : (ABRecordRef) person : (ABPropertyID) property : (ABMultiValueIdentifier)identifier {
ABMultiValueRef mvPropertyRef = ABRecordCopyValue(person, property);
int propertyIndex = ABMultiValueGetIndexForIdentifier( mvPropertyRef, identifier);
NSString *recipientAddress = (__bridge NSString *)(ABMultiValueCopyValueAtIndex( mvPropertyRef, propertyIndex));
}
These two methods might help you to get the selected person's email id
- (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker
shouldContinueAfterSelectingPerson:(ABRecordRef)person
property:(ABPropertyID)property
identifier:(ABMultiValueIdentifier)identifier
{
ABPersonViewController *controller = [[ABPersonViewController alloc] init];
controller.displayedPerson = person;
controller.displayedProperties = [NSArray arrayWithObject:[NSNumber numberWithInt:kABPersonEmailProperty]];
controller.personViewDelegate = self;
[peoplePicker pushViewController:controller animated:YES];
[controller release];
return NO;
}
-(BOOL)personViewController:(ABPersonViewController *)personViewController
shouldPerformDefaultActionForPerson:(ABRecordRef)person
property:(ABPropertyID)property
identifier:(ABMultiValueIdentifier)identifierForValue
{
ABMutableMultiValueRef multiEmail = ABRecordCopyValue(person, property);
NSString *emailAddress = (NSString *) ABMultiValueCopyValueAtIndex(multiEmail, identifierForValue);
NSLog(#"strEmail %#",emailAddress);
ABPeoplePickerNavigationController *peoplePicker = (ABPeoplePickerNavigationController *)personViewController.navigationController;
[peoplePicker dismissViewControllerAnimated:YES completion:nil];
return NO;
}
Related
I am trying to get the email value of an address book contact.
I need to capture which email the user click and I can figure out how to get the syntax right.
I used an example which picked the first email available, but I am now trying to switch it to the email that the user selects. I started writing //NSString* email = ABRecordCopyValue(property, );
or how to get the index value of what the user selected. If I had the index value of the email selected, I could reuse the code that I had commented out.
- (BOOL)peoplePickerNavigationController:
(ABPeoplePickerNavigationController *)peoplePicker
shouldContinueAfterSelectingPerson:(ABRecordRef)person
property:(ABPropertyID)property
identifier:(ABMultiValueIdentifier)identifier
{
NSString* name = (__bridge_transfer NSString*)ABRecordCopyValue(person, kABPersonFirstNameProperty);
self.userName.text = name;
self.myMessage.recpipientName = name;
//NSString* email = ABRecordCopyValue(property)
ABMultiValueRef emails = ABRecordCopyValue(person, kABPersonEmailProperty);
// if (ABMultiValueGetCount(emails) > 0) {
// email = (__bridge_transfer NSString*)
// ABMultiValueCopyValueAtIndex(emails, 0);
// } else {
// email = #"[None]";
// }
self.userEmail.text = email;
self.myMessage.recipientEmail = email;
CFRelease(emails);
return NO;
}
This is example code comes directly from my book (http://www.apeth.com/iOSBook/ch31.html#_abpeoplepickernavigationcontroller):
- (BOOL)peoplePickerNavigationController:
(ABPeoplePickerNavigationController *)peoplePicker
shouldContinueAfterSelectingPerson:(ABRecordRef)person
property:(ABPropertyID)property
identifier:(ABMultiValueIdentifier)identifier {
ABMultiValueRef emails = ABRecordCopyValue(person, property);
CFIndex ix = ABMultiValueGetIndexForIdentifier(emails, identifier);
CFStringRef email = ABMultiValueCopyValueAtIndex(emails, ix);
NSLog(#"%#", email); // do something with the email here
if (email) CFRelease(email);
if (emails) CFRelease(emails);
[self dismissViewControllerAnimated:YES completion:nil];
return NO;
}
I am building an app that requires me to pick first name and last name from contact. On running with Build Analyser I got memory leak in this chunk of codes.
ABMutableMultiValueRef fName = ABRecordCopyValue(person, kABPersonFirstNameProperty);
ABMutableMultiValueRef lName = ABRecordCopyValue(person, kABPersonLastNameProperty);
if(fName){
self.firstNameText.text = fName;
}
if (lName) {
self.lastNameText.text = lName;
}
CFRelease(fName);
CFRelease(lName);
I am really tired of fixing it but was unable to. Kindly help me out.
Any kind of help would be highly appriciated.
Thanks in advance!!
Hello this are the delegate methods.
in - (BOOL)peoplePickerNavigationController: (ABPeoplePickerNavigationController *)peoplePicker shouldContinueAfterSelectingPerson:(ABRecordRef)person method you can retrive any user infromation
like kABPersonFirstNameProperty for first name,kABPersonLastNameProperty for last name property
- (void)peoplePickerNavigationControllerDidCancel:(ABPeoplePickerNavigationController *)peoplePicker {
// assigning control back to the main controller
[self dismissModalViewControllerAnimated:YES];
}
- (BOOL)peoplePickerNavigationController: (ABPeoplePickerNavigationController *)peoplePicker shouldContinueAfterSelectingPerson:(ABRecordRef)person {
NSString *firstname=(NSString *)ABRecordCopyValue(person, kABPersonFirstNameProperty);
Usernametf.text=firstname;
// NSMutableDictionary *dict=[[NSMutableDictionary alloc] initWithObjectsAndKeys:firstname,#"FirstName", nil];
//[selectedemailArray addObject:dict];
// NSLog(#"\n array is %#",selectedemailArray);
//[objDatabase insertArray:selectedemailArray forTable:#"EmailList"];
//[objDatabase insertDictionary:dict forTable:#"EmailList"];
// [dict release];
// dict =nil;
// remove the controller
[self dismissModalViewControllerAnimated:YES];
return NO;
}
- (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker shouldContinueAfterSelectingPerson:(ABRecordRef)person property:(ABPropertyID)property identifier:(ABMultiValueIdentifier)identifier{
return NO;
}
let me know is it working or not..!!!!
Happy coding!!!!!
As per my requirement,
i need to get email id's from contacts.
And i need to write a code for this in a separate class in a method.To get call this integrate classes into my project simply call that method.
This is what i need.
for this my code in ownServices is like this.
-(NSString *)getSelectedNumberFromContatcs {
ABPeoplePickerNavigationController *peoplePickerController = [[ABPeoplePickerNavigationController alloc] init];
peoplePickerController.peoplePickerDelegate = self;
[self presentModalViewController:peoplePickerController animated:NO];
[peoplePickerController release];
return aNSString;
}
- (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker
shouldContinueAfterSelectingPerson:(ABRecordRef)person {
// NSString *name = (NSString *)ABRecordCopyValue(person, kABPersonPhoneProperty);
return YES;
}
- (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker
shouldContinueAfterSelectingPerson:(ABRecordRef)person
property:(ABPropertyID)property
identifier:(ABMultiValueIdentifier)identifier {
if (property == kABPersonPhoneProperty) {
ABMultiValueRef emails = ABRecordCopyValue(person, property);
CFStringRef phonenumberselected = ABMultiValueCopyValueAtIndex(emails, identifier);
// CFStringRef emailLabelSelected = ABMultiValueCopyLabelAtIndex(emails, identifier);
// CFStringRef emailLabelSelectedLocalized = ABAddressBookCopyLocalizedLabel(ABMultiValueCopyLabelAtIndex(emails, identifier));
aNSString = (NSString *)phonenumberselected;
// Return to the main view controller.
[ self dismissModalViewControllerAnimated:YES ];
return NO;
}
return YES ;
}
- (void)peoplePickerNavigationControllerDidCancel:(ABPeoplePickerNavigationController *)peoplePicker
{
[ self dismissModalViewControllerAnimated:YES ];
}
i am calling this in myclassviewcontroller like this.
- (void)viewDidLoad {
[super viewDidLoad];
ownServices *obj = [[ownServices alloc]init];
[obj getSelectedNumberFromContatcs];
}
But contatcs viewcontraoller is not opened.
But i try same code in view controller in a button action like this
-(IBAction)openContacts {
ABPeoplePickerNavigationController *peoplePickerController = [[ABPeoplePickerNavigationController alloc] init];
peoplePickerController.peoplePickerDelegate = self;
[self presentModalViewController:peoplePickerController animated:NO];
[peoplePickerController release];
}
Then contacts viewconrtroller opened.
i did n't why view controller is not opened by calling it in a method.
is it possible to do like this.
can any one please help me.
Thank u in advance.
Because the class you are using is inherited from NSObject not UIViewController so the [self presentModalViewController:peoplePickerController animated:NO]; will not work. Also
you have written this method in a wrong way
-(NSString *)getSelectedNumberFromContatcs {
ABPeoplePickerNavigationController *peoplePickerController = [[ABPeoplePickerNavigationController alloc] init];
peoplePickerController.peoplePickerDelegate = self;
[self presentModalViewController:peoplePickerController animated:NO];
[peoplePickerController release];
return aNSString;
}
Let me know what actually you want to do?
Instead of peoplePickerController.peoplePickerDelegate = self is it possible to use the reference of your main View Controller?
I am getting phone number from the address book for that i am using this code.
- (IBAction)contacts {
ABPeoplePickerNavigationController *peoplePickerController = [[ABPeoplePickerNavigationController alloc] init];
peoplePickerController.peoplePickerDelegate = self;
[self presentModalViewController:peoplePickerController animated:NO];
[peoplePickerController release];
}
- (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker
shouldContinueAfterSelectingPerson:(ABRecordRef)person {
return YES;
}
- (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker
shouldContinueAfterSelectingPerson:(ABRecordRef)person
property:(ABPropertyID)property
identifier:(ABMultiValueIdentifier)identifier {
if (property == kABPersonPhoneProperty) {
ABMultiValueRef phonenumbers = ABRecordCopyValue(person, property);
CFStringRef phonenumberselected = ABMultiValueCopyValueAtIndex(phonenumbers, identifier);
NSString *aNSString = (NSString *)phonenumberselected;
if ([share_toadd length] == 0) {
[share_toadd appendString:aNSString];
}
else {
[share_toadd appendString:#","];
[share_toadd appendString:aNSString];
}
share_textfield.text = share_toadd;
// Return to the main view controller.
[ self dismissModalViewControllerAnimated:YES ];
return NO;
[share_textfield release];
}
return YES;
}
but i am getting potential leak at CFStringRef
Potential leak of an object allocated on line 1126
Call to function 'ABRecordCopyValue' returns a Core Foundation object with a +1 retain count (owning reference)
Object allocated on line 1126 is no longer referenced after this point and has a retain count of +1 (object leaked)
can any one pls help me.
how can i resolve it.
You should call CFRelease(phonenumbersselected) when you're done using the object.
i have the contact list showing up perfectly in the simulator. it takes the phone number and places it in the text box. so i decided to try it on my iphone and it actually executes the thing i tap on. it calls the number instead of putting the number ito the textbox. heres the code:
- (IBAction) adressBook: (id) sender {
// creating the picker
ABPeoplePickerNavigationController *picker = [[ABPeoplePickerNavigationController alloc] init];
// place the delegate of the picker to the controll
picker.peoplePickerDelegate = self;
// showing the picker
[self presentModalViewController:picker animated:YES];
// releasing
[picker release];
}
- (void)peoplePickerNavigationControllerDidCancel:(ABPeoplePickerNavigationController *)peoplePicker {
// assigning control back to the main controller
[self dismissModalViewControllerAnimated:YES];
}
- (BOOL)peoplePickerNavigationController: (ABPeoplePickerNavigationController *)peoplePicker shouldContinueAfterSelectingPerson:(ABRecordRef)person {
/*
ABMultiValueRef multi = ABRecordCopyValue(person, kABPersonPhoneProperty);
num.text = (NSString*)ABMultiValueCopyValueAtIndex(multi, 0);
//[self dismissModalViewControllerAnimated:YES];
*/
return YES;
}
- (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker shouldContinueAfterSelectingPerson:(ABRecordRef)person property:(ABPropertyID)property identifier:(ABMultiValueIdentifier)identifier{
NSLog(#"inbool");
ABMultiValueRef phonePro = ABRecordCopyValue(person, property);
int idx = ABMultiValueGetIndexForIdentifier(phonePro, identifier);
num.text = (NSString*)ABMultiValueCopyValueAtIndex(phonePro, idx);
[self dismissModalViewControllerAnimated:YES];
/*
ABMultiValueRef multi = ABRecordCopyValue(person, property);
num.text = (NSString*)ABMultiValueCopyValueAtIndex(multi, identifier);
*/
return YES;
}
and sorry if not formatted correctly, new to stackoverflow.
Your peoplePickerNavigationController:shouldContinueAfterSelectingPerson:property:identifier: needs to return NO so that the phone does not perform it's default action. You then close the picker yourself.
-(BOOL) peoplePickerNavigationController: (ABPeoplePickerNavigationController *) peoplePicker
shouldContinueAfterSelectingPerson: (ABRecordRef) person
property: (ABPropertyID) property
identifier: (ABMultiValueIdentifier) identifier
{
NSLog(#"inbool");
ABMultiValueRef phonePro = ABRecordCopyValue(person, property);
int idx = ABMultiValueGetIndexForIdentifier(phonePro, identifier);
num.text = (NSString)ABMultiValueCopyValueAtIndex(phonePro, idx);
[peoplePicker dismissModalViewControllerAnimated: YES];
return NO;
}