potential leak at CFStringRef while getting phone number from contacts - iphone

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.

Related

ABPeoplePickerNavigationControllerDelegate: shouldContinueAfterSelectingPerson giving bad ABMultiValue id with email addresses

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

ABPeoplePickerNavigationController display all contact data in a single cel

Hi i am developing a app where when i click contacts it goes to ABpeoplePicekrNavigationcontroller and display all contacts in the form of list in the table.But i want to select all contacts so that i want to perform some action.So how can i achive this.
I am not sure this is the right question to ask.Actually i am trying to send the contact information to next screen instead of selecting single contact information everytime i want to select whole contact list.So how can i do this??
I thought i show them to show in single cell even though space doesnt fit in single cell.just show them single cell so that selecting one cell which contains all contact information would be better to send..
So can anyone suggest me right way to select all the contacts list rather than selecting one contact..I donno whether we can do this or not??if so how???if not what is the other way??
Here is the below code where i am using for accessing the contact list.
- (IBAction)configureMyContact:(id)sender {
ABPeoplePickerNavigationController *peoplePicker = [[ABPeoplePickerNavigationController alloc] init];
peoplePicker.peoplePickerDelegate = self;
peoplePicker.navigationBar.topItem.title = NSLocalizedString(#"CHOOSE_CONTACT_TITLE", #"Defining my contact title.");
[self presentModalViewController:peoplePicker animated:YES];
[peoplePicker release];
}
- (void)peoplePickerNavigationControllerDidCancel:(ABPeoplePickerNavigationController *)peoplePicker {
[self dismissModalViewControllerAnimated:YES];
}
- (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker
shouldContinueAfterSelectingPerson:(ABRecordRef)person {
myContactID = ABRecordGetRecordID(person);
[self refreshMyContactButton];
[self saveMyContactID:myContactID];
[self dismissModalViewControllerAnimated:YES];
return NO;
}
- (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker
shouldContinueAfterSelectingPerson:(ABRecordRef)person
property:(ABPropertyID)property
identifier:(ABMultiValueIdentifier)identifier{
return NO;
}
You can get your record using this
- (void)getPersonOutOfAddressBook
{
ABAddressBookRef addressBook = ABAddressBookCreate();
if (addressBook != nil)
{
NSLog(#"Succesful.");
NSArray *allContacts = (__bridge_transfer NSArray *)ABAddressBookCopyArrayOfAllPeople(addressBook);
NSUInteger i = 0;
for (i = 0; i < [allContacts count]; i++)
{
ABRecordRef contactPerson = (__bridge ABRecordRef)allContacts[i];
NSString *firstName = (__bridge_transfer NSString *)ABRecordCopyValue(contactPerson, kABPersonFirstNameProperty);
NSString *lastName = (__bridge_transfer NSString *)ABRecordCopyValue(contactPerson, kABPersonLastNameProperty);
ABMultiValueRef mobile=ABRecordCopyValue(contactPerson, kABPersonPhoneProperty);
for (int k=0;k<ABMultiValueGetCount(mobile); k++)
{
NSString *mobileNo = (__bridge_transfer NSString *)ABMultiValueCopyValueAtIndex(mobile, k);
}
//email
ABMultiValueRef emails = ABRecordCopyValue(contactPerson, kABPersonEmailProperty);
NSUInteger j = 0;
for (j = 0; j < ABMultiValueGetCount(emails); j++)
{
NSString *email = (__bridge_transfer NSString *)ABMultiValueCopyValueAtIndex(emails, j);
}
}
}
CFRelease(addressBook);
}

Memory leak in ABRecordCopyValue

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!!!!!

how to get open contacts by calling method instead of button click

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?

ABPeoplePickerNavigationController actually executing

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