How do you retrieve ONLY the select property from your iOS contacts?

Deadly 提交于 2019-12-11 13:47:48

问题


we're having an issue where incorrect selections are being returned from the contacts database on some devices. Is there a way to modify the below code to only return the selected item from a persons contact information? In this case we want the exact selected email address from a persons contact to be returned.

Thanks in advance for the help! Heres the code...

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

    NSMutableDictionary *contactInfoDict = [[NSMutableDictionary alloc]
                                            initWithObjects:@[@"", @"", @""]
                                            forKeys:@[@"first_name", @"last_name",     @"email"]];

    // Use a general Core Foundation object.
    CFTypeRef generalCFObject = ABRecordCopyValue(person, kABPersonFirstNameProperty);

    // Get the first name.
    if (generalCFObject) {
        [contactInfoDict setObject:(__bridge NSString *)generalCFObject     forKey:@"first_name"];
        CFRelease(generalCFObject);
    }

    // Get the last name.
    generalCFObject = ABRecordCopyValue(person, kABPersonLastNameProperty);
    if (generalCFObject) {
        [contactInfoDict setObject:(__bridge NSString *)generalCFObject     forKey:@"last_name"];
        CFRelease(generalCFObject);
    }

    // Load selected email addre'
    if (property == kABPersonEmailProperty) {
        ABMultiValueRef emails = ABRecordCopyValue(person, property);
        CFIndex ix = ABMultiValueGetIndexForIdentifier(emails, identifier);
        CFStringRef email = ABMultiValueCopyValueAtIndex(emails, ix);

        emailAccount = (__bridge NSString *)(email);
        [contactInfoDict setObject:emailAccount forKey:@"email"];

        if (email) CFRelease(email);
        if (emails) CFRelease(emails);
    }

    // init array
    if (_arrContactsData == nil) {
        _arrContactsData = [[NSMutableArray alloc] init];
    }

    // Send contact to server
    [self sendContact:contactInfoDict];

    // Set data for contacts
    [_arrContactsData addObject:contactInfoDict];

    // Reload the table view data.
    [self.myTable reloadData];

    // Dismiss the address book view controller.
    [_addressBookController dismissViewControllerAnimated:YES completion:nil];

    return NO;
}

回答1:


Your code is correct.

Are the users experiencing the problem using iOS 8, by any chance? I discovered a bug in iOS 8 beta 6. If you:

  1. Create a contact with email addresses:

  2. Edit the contact, adding an email address and deleting one of the other email addresses:

    (Note, don't just edit one of the email addresses, but rather add a new email address and remove and old one.)

  3. In iOS 7, if you iterate through the email addresses, you will see:

    {
        identifier = 1;
        index = 0;
        label = "_$!<Work>!$_";
        value = "work@gmail.com";
    },
    {
        identifier = 2;
        index = 1;
        label = "_$!<Other>!$_";
        value = "other@gmail.com";
    }
    

    This is correct. (When the contact was first created, the identifiers were 0 and 1, when I add the "other" email address, that gets an identifier of 2; when I delete the "home" email address, the email address with the identifier of 0 is deleted, but the other identifiers are correctly unaltered.) Thus, if you tap on the "work" email address, shouldContinueAfterSelectingPerson will return an ABMultiValueIdentifier of 1, which translates to a CFIndex of 0, which will correctly return the "work" email address.

    In iOS 8 Beta 6, however, the ABMultiValueRef is incorrectly represented as:

    {
        identifier = 0;
        index = 0;
        label = "_$!<Work>!$_";
        value = "work@gmail.com";
    },
    {
        identifier = 1;
        index = 1;
        label = "_$!<Other>!$_";
        value = "other@gmail.com";
    }
    

    These identifiers are incorrect. Worse, if you tap on the "work" email address, didSelectPerson (which replaces the deprecated shouldContinueAfterSelectingPerson) will return a ABMultiValueIdentifier of 1 (which is what it should have been ... it looks like this delegate method returns the appropriate identifier, but that the ABRecordRef for this edited record has the wrong identifiers ... not sure how they did that!), which translates to a CFIndex of 1, which will correctly return the "other" email address (!).

    Worse, if you tapped on the "other" email address, didSelectPerson will return a ABMultiValueIdentifier of 2 (which is what it should have been), but if you try to retrieve the CFIndex, you'll get -1 (because no such ABMultiValueIdentifier exists) and because the app doesn't check for this, any attempt to use ABMultiValueCopyValueAtIndex with this invalid index will result in crash!

This bug seems to be fixed in the iOS8 GM seed, so it appears to be a beta problem only.



来源:https://stackoverflow.com/questions/25756990/how-do-you-retrieve-only-the-select-property-from-your-ios-contacts

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!