Check if ABMultiValueRef is has no values - ios

I want to check if a contact in my user's addressbook a phone number has. If he does, I want to display that name in an UITableView
I've tried to check for phoneNumbers != nil, but that doesn't work. This is my entire code:
ABMultiValueRef phoneNumbers = ABRecordCopyValue(person, kABPersonPhoneProperty);
if(phoneNumbers != nil){
[_numbers addObject:[NSString stringWithFormat:#"%#", phoneNumbers]];
}

Use ABMultiValueGetCount to check if phoneNumbers has any values in it.
example based on question:
ABMultiValueRef phoneNumbers = ABRecordCopyValue(person, kABPersonPhoneProperty);
if(ABMultiValueGetCount(phoneNumbers)){
[_numbers addObject:[NSString stringWithFormat:#"%#", phoneNumbers]];
}

Related

How to check if a contact in Address Book has multiple numbers in iOS?

I have a requirement to determine if a contact that is saved in the address book has multiple mobile numbers.
I have the record ID of a Contact and I need to check if that contact has multiple mobile numbers.
Is this possible?
Got the Answer!!! I have written a method to get the total count of mobile numbers for a contact
-(NSInteger)getCountOfTotalMobileNumbersForContact:(ContactData *)contactData{
NSInteger totalCountOfMobileNumbers = 0;
ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, NULL);
ABRecordRef contact = ABAddressBookGetPersonWithRecordID(addressBook, (int)contactData.mRecordID);
if(contact != nil)
{
self.phoneNumbers = ABRecordCopyValue(contact, kABPersonPhoneProperty);
NSString *lFirstName = (__bridge_transfer NSString*)ABRecordCopyValue(contact, kABPersonFirstNameProperty);
NSString *lLastName = (__bridge_transfer NSString*)ABRecordCopyValue(contact, kABPersonLastNameProperty);
NSString *fullName = lFirstName;
if (lLastName.length) {
fullName = [[lFirstName stringByAppendingString:#" "] stringByAppendingString:lLastName];
}
totalCountOfMobileNumbers = ABMultiValueGetCount(self.phoneNumbers);
}
return totalCountOfMobileNumbers;
}

Handling actions ABPersonViewController with linked contacts on iOS7

I am having an issue handling an action on an ABPersonViewController when the view controller is displaying a merged contact in iOS 7.
In the below example the ABPersonViewController showed 7 rows for the contact being displayed but when I fetch the ABMultiValueRef for the property it returns 8 rows where the first row was hidden because it was a duplicate on this combined contact.
When the value is read for the index it is the one that is hidden so all values read are one off the one that was displayed in the ABPersonViewController
-(BOOL)personViewController:(ABPersonViewController *)personViewController shouldPerformDefaultActionForPerson:(ABRecordRef)person property:(ABPropertyID)property identifier:(ABMultiValueIdentifier)identifier{
if (property == kABPersonPhoneProperty){
ABMultiValueRef phone = ABRecordCopyValue(person, property);
CFIndex theindex = ABMultiValueGetIndexForIdentifier(phone, identifier);
NSString *selectedValue = (NSString *)ABMultiValueCopyValueAtIndex(phone, the index);
// DO SOMETHING WITH THE SELECTED VALUE
CFSafeRelease(phone);
CFSafeRelease(selectedValue);
}
return NO;
}
Is there a way to get the correct value for the index when the contacts are combined, or is there a way to get the MultiValueRef for the property that was actually displayed in the ABPersonViewController?
Try This :
- (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker
shouldContinueAfterSelectingPerson:(ABRecordRef)person {
ABMultiValueRef phoneNumberProperty = ABRecordCopyValue(person, kABPersonPhoneProperty);
phoneNumbers = (__bridge NSArray*)ABMultiValueCopyArrayOfAllValues(phoneNumberProperty);
NSLog(#"%#",phoneNumbers);
CFRelease(phoneNumberProperty);
return NO;
}
ABPropertyType pt = ABPersonGetTypeOfProperty(property);
NSString *phoneNumber;
if ((pt & kABMultiValueMask) == kABMultiValueMask) {
ABMultiValueRef phoneProperty = ABRecordCopyValue(person,property);
CFIndex idx = ABMultiValueGetIndexForIdentifier(phoneProperty, identifier);
phoneNumber = (__bridge NSString *)ABMultiValueCopyValueAtIndex(phoneProperty,idx);
CFRelease(phoneProperty);
}

Copy contacts phone numbers to array using ABAdressPhoneBookRef

I think I need to use ABMultiValueCopyArrayOfAllValues to grab all phone numbers from my ABAddressBookRef reference variable.
(If this is not the correct way to do it, please give me a correct way; ANY way that gives me access to contact phone numbers will do)
What I'd like to do now, is grab my user's contact's phone numbers(preferably their cell) and add that to an array.
How do I grab just the numbers and add that to an array?
Any help, suggestions, or advice with this is greatly appreciated in advice, I'm not finding this anywhere.
Thanks.
If I were you, I would use this approach:
NSMutableArray *allPhoneNumbers = #[].mutableCopy;
NSArray *allContact = (__bridge NSArray*)ABAddressBookCopyArrayOfAllPeople(book);
for (id rec in allContacts){
ABMultiValueRef mvr = ABRecordCopyValue((__bridge ABRecordRef)rec, kABPersonPhoneProperty);
NSArray *currentNums = (__bridge NSArray*) ABMultiValueCopyArrayOfAllValues(mvr);
[allPhoneNumbers addObjectsFromArray: currentNums];
}
I have not tested this, but it should work. Tell me if you have any issues.
If you want just one contact's numbers (the above gets every contact), use this code.
ABMultiValueRef mvr = ABRecordCopyValue(yourRecordRef, kABPersonPhoneProperty);
NSArray *currentNums = (__bridge NSArray*) ABMultiValueCopyArrayOfAllValues(mvr);
[allPhoneNumbers addObjectsFromArray: currentNums];
ABMultiValueRef phoneNumbers = ABRecordCopyValue(ref, kABPersonPhoneProperty);
for(CFIndex j = 0; j < ABMultiValueGetCount(phoneNumbers); j++)
{
CFStringRef phoneNumberRefCF = ABMultiValueCopyValueAtIndex(phoneNumbers, j);
CFStringRef locLabelCF = ABMultiValueCopyLabelAtIndex(phoneNumbers, j);
NSString *phoneLabelCF =(NSString*) ABAddressBookCopyLocalizedLabel(locLabelCF);
NSString *phoneNumberCF = (NSString *)phoneNumberRefCF;
CFRelease(phoneNumberRefCF);
CFRelease(locLabelCF);
NSLog(#" - %# (%#)", phoneNumberCF, phoneLabelCF);
}

kABPersonPhoneProperty Only Detecting Home Phone Numbers

I followed Apple's tutorial on obtaining a contact's phone number and it works great but it only detects phone numbers with the "Home" label. Here is my code:
- (void)displayPerson:(ABRecordRef)person {
NSString* phone = nil;
ABMultiValueRef phoneNumbers = ABRecordCopyValue(person,
kABPersonPhoneProperty);
if (ABMultiValueGetCount(phoneNumbers) > 0) {
phone = (__bridge_transfer NSString*)
ABMultiValueCopyValueAtIndex(phoneNumbers, 0);
} else {
phone = #"[None]";
}
self.contactNumber.text = phone;
CFRelease(phoneNumbers); }
Anyone know why it is doing this?
That's because this line
ABMultiValueCopyValueAtIndex(phoneNumbers, 0);
tells it to get the first phone number, i.e "Home" number.
See this post:
Access to people info in iPhone address book

Contact number stays nil

I have an mutableArray and put the number of a contact in it.
I use the following code:
ABMultiValueRef phoneNumbers = (ABMultiValueRef)ABRecordCopyValue(person, kABPersonPhoneProperty);
CFRelease(phoneNumbers);
number = (__bridge NSString*)ABMultiValueCopyValueAtIndex(phoneNumbers, 0);
[thenumbers addObject:number];
In order to retrieve it, I do this:
Contacts *num = [thenumbers objectAtIndex:indexPath.row];
NSString *numbers = [NSString stringWithFormat:#"%#", [num number]];
cell.detailTextLabel.text = numbers;
I set breakpoints and it stops at the right lines. I also tried
NSLog(#"%#", number);
And it returns the numbers. And yes I have reloadDate in viewWillappear.
You're releasing phoneNumbers straight after copying to it. Try moving it to after you use it.
Or, better still, transfer the ownership to the NSString object through ARC
ABMultiValueRef phoneNumbers = (ABMultiValueRef)ABRecordCopyValue(person, kABPersonPhoneProperty);
number = (__bridge_transfer NSString*)ABMultiValueCopyValueAtIndex(phoneNumbers, 0);
And there is no need to call CFRelease(phoneNumbers) at all.
As for getting the numbers into the cell, you're getting confused about your types. You're putting an NSString into theNumber but your pulling out a Contacts. And then sending it some kind of number message.
You've put a string in the array, you can only pull out a string or a subclass.
NSString *numbers = [thenumbers objectAtIndex:indexPath.row];
cell.detailTextLabel.text = numbers;
In the following code,
ABMultiValueRef phoneNumbers = (ABMultiValueRef)ABRecordCopyValue(person, kABPersonPhoneProperty);
CFRelease(phoneNumbers);
number = (__bridge NSString*)ABMultiValueCopyValueAtIndex(phoneNumbers, 0);
You are releasing the phoneNumbers and then you are accesing the variable. Change it to as follows.
ABMultiValueRef phoneNumbers = (ABMultiValueRef)ABRecordCopyValue(person, kABPersonPhoneProperty);
number = (__bridge NSString*)ABMultiValueCopyValueAtIndex(phoneNumbers, 0);
CFRelease(phoneNumbers);

Resources