user3003787
user3003787

Reputation: 77

peoplePickerNavigationController: shouldContinueAfterSelectingPerson: property: identifier:

I am trying to get selected mobile phone number with

ABMultiValueRef phones = ABRecordCopyValue(person, property);
CFStringRef phoneNumber = ABMultiValueCopyValueAtIndex(phones, identifier);

I have a contact with several mobile phones (all labeled 'mobile'). When I select the first one, phoneNumber gives me the first one, but if I select any consecutive one, phoneNumber gives me the previous number:

Contact: Jay Jaymes mobile +1111111111 mobile +2222222222 mobile +3333333333

Tap first one, phoneNumber = +1111111111

Tap second one, phoneNumber = +1111111111

Tap third one, phoneNumber = +2222222222

Upvotes: 4

Views: 1731

Answers (4)

Bhumeshwer katre
Bhumeshwer katre

Reputation: 4671

This is code I use. And It will give correct phone number only

  - (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker shouldContinueAfterSelectingPerson:(ABRecordRef)person property:(ABPropertyID)property identifier:(ABMultiValueIdentifier)identifier {

        if (property == kABPersonPhoneProperty) {

            ABMultiValueRef phoneProperty = ABRecordCopyValue(person,property);
            CFIndex peopleIndex = ABMultiValueGetIndexForIdentifier(property, identifier);
            NSString *phone = (__bridge_transfer NSString*)ABMultiValueCopyValueAtIndex(phoneProperty, peopleIndex);

            [self dismissModalViewControllerAnimated:YES];
        }
    return NO;
}

Upvotes: 4

Rob
Rob

Reputation: 437552

You should not be using the identifier as the index within ABMultiValueCopyValueAtIndex. You should call ABMultiValueGetIndexForIdentifier to convert the ABMultiValueIdentifier identifier into a CFIndex index:

ABMultiValueRef phones = ABRecordCopyValue(person, property);
CFIndex index = ABMultiValueGetIndexForIdentifier(phones, identifier);
NSString *phoneNumber = CFBridgingRelease(ABMultiValueCopyValueAtIndex(phones, index));
CFRelease(phones);

Generally, the ABMultiValueIdentifier values match the CFIndex values retrieved by ABMultiValueGetIndexForIdentifier, but if a contact was edited (specifically if one of the earlier phone numbers was deleted), using the ABMultiValueIdentifier in ABMultiValueCopyValueAtIndex will return the wrong record.

Upvotes: 0

user3003787
user3003787

Reputation: 77

Ended up implementing it this way:

- (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker shouldContinueAfterSelectingPerson:(ABRecordRef)person property:(ABPropertyID)property identifier:(ABMultiValueIdentifier)identifier
{
   if (property == kABPersonPhoneProperty)
    {
        ABMultiValueRef phones = ABRecordCopyValue(person, property);
        CFStringRef phoneNumber = ABMultiValueCopyValueAtIndex(phones, identifier);
        NSLog(@"%@", phoneNumber);
        NSMutableString *tmp = [NSMutableString stringWithFormat:@"%@", (__bridge_transfer NSString *)phoneNumber];
        NSString *strippedPhoneNumber = [tmp stringByReplacingOccurrencesOfString:@" " withString:@""];
        NSCharacterSet *doNotWant = [NSCharacterSet characterSetWithCharactersInString:@"()-"];
        strippedPhoneNumber = [[strippedPhoneNumber componentsSeparatedByCharactersInSet: doNotWant] componentsJoinedByString: @""];
        NSString *firstName = (__bridge_transfer NSString *)ABRecordCopyValue(person, kABPersonFirstNameProperty);
        [peoplePicker dismissViewControllerAnimated:YES completion:nil];
        return NO;
}

Upvotes: 0

Grzegorz Krukowski
Grzegorz Krukowski

Reputation: 19802

You can easily iterate like that. Try NSLoging that code to make sure it works. I think you have some bugs in your "choosing" logic.

ABMultiValueRef phones = ABRecordCopyValue(person, kABPersonPhoneProperty);

for (CFIndex i=0; i < ABMultiValueGetCount(phones); i++) 
{
   NSString* phoneLabel = (NSString*)ABMultiValueCopyLabelAtIndex(phones, i);
   NSString* phoneNumber = ABMultiValueCopyValueAtIndex(phones, i);

   //release variables since you were using COPY !!!
   CFRelease(phoneNumber);
   CFRelease(phoneLabel);
}

CFRelease(phones);

Upvotes: 0

Related Questions