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!!!!!
Related
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;
}
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 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;
}
I am currently able to successfully access and get data from the peoplePickerNavigationController, but what I would like to do is have the email address of the contact be accessed, then the modal window dismissed when the contact name is pressed.
Scenario:
"Button is clicked to add a contact
AddressBook Modal Window slides into view
Name of Contact is pressed
If available, the contact's email address is stored in an array
Dismiss modal window"
My current code consists of:
- (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker shouldContinueAfterSelectingPerson:(ABRecordRef)person property:(ABPropertyID)property identifier:(ABMultiValueIdentifier)identifier {
ABMultiValueRef container = ABRecordCopyValue(person, property);
CFStringRef contactData = ABMultiValueCopyValueAtIndex(container, identifier);
CFRelease(container);
NSString *contactString = [NSString stringWithString:(NSString *)contactData];
CFRelease(contactData);
NSLog(#"Value is: %#", contactString);
[self dismissModalViewControllerAnimated:YES];
return NO;
}
Here is what i do.
if(property == kABPersonEmailProperty) {
CFTypeRef prop = ABRecordCopyValue(person, property);
CFIndex index = ABMultiValueGetIndexForIdentifier(prop, identifierForValue);
NSString *email = (NSString *)ABMultiValueCopyValueAtIndex(prop, index);
...
CFRelease(prop);
[email release];
}