ABMultilValueGetIndexForIdentifier возвращает неверный индекс, когда у контакта есть LinkedContacts
Я заметил ошибку в логике, которую мы используем для обработки выбора конкретного электронного письма для контакта, представленного ABPeoplePickerNavigationController. Ошибка возникает именно тогда, когда у нашего контакта есть Связанные контакты из Твиттера или Facebook.
Я дважды проверил нашу логику по нескольким связанным вопросам Stackru и, похоже, все делаю "правильно":
- iOS Получение адреса электронной почты выбранных контактов в массиве
- Как получить электронную почту, используя ABPeoplePicker?
- Как получить выбранный пользователем адрес электронной почты от ABPeoplePicker?
Вот код для загрузки ABPeoplePicker после нажатия кнопки:
- (void)setUpChooseContactButton
{
@weakify(self)
[self.chooseContactButton addEventHandler:^(id sender) {
@strongify(self)
ABPeoplePickerNavigationController *picker = [[ABPeoplePickerNavigationController alloc] init];
picker.peoplePickerDelegate = self;
picker.displayedProperties = @[@(kABPersonEmailProperty)];
picker.delegate = self;
[self presentViewController:picker animated:YES completion:nil];
} forControlEvents:UIControlEventTouchUpInside];
}
Позже, когда пользователь нажимает на электронную почту для выбранного контакта, мы обрабатываем его следующим образом:
- (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker
shouldContinueAfterSelectingPerson:(ABRecordRef)person
property:(ABPropertyID)property
identifier:(ABMultiValueIdentifier)identifier
{
if (property == kABPersonEmailProperty)
{
ABMultiValueRef multiEmail = ABRecordCopyValue(person, kABPersonEmailProperty);
CFIndex selectedIndex = ABMultiValueGetIndexForIdentifier(multiEmail, identifier);
CFStringRef selectedEmail = ABMultiValueCopyValueAtIndex(multiEmail, selectedIndex);
NSLog(@"Doing something with %@", selectedEmail);
if (selectedEmail) CFRelease(selectedEmail);
if (multiEmail) CFRelease(multiEmail);
}
[self dismissViewControllerAnimated:YES completion:nil];
return NO;
}
Это прекрасно работает, когда у контакта нет связанных контактов, например, Facebook, однако, когда это происходит, адрес электронной почты, напечатанный здесь, не будет выбранным пользователем.
Например, в моих контактах есть друг, которого мы назовем Джоном Сноу, мы хорошие друзья, поэтому я связан с ним в iCloud, 2 разных учетных записях Gmail и Facebook.
Когда я перехожу на страницу контактов Джона Сноу, я вижу следующие 5 электронных писем:
- john.snow@gmail.com
- jsnow@gmail.com
- lordsnow@nightswatch.org
- john.snow@facebook.com
- john@winterfellstarks.com
А также ячейки для каждого из связанных контактов.
Поэтому, если я нажму на lordsnow@nightswatch.org (индекс 2 в списке представленных электронных писем) и укажу точку останова в обратном вызове shouldContinueAfterSelecting в NSLog и выведу соответствующие переменные, это то, что я увижу:
(lldb) po multiEmail
ABMultiValueRef 0x17737ca0 with 8 value(s)
0: null (0x3b864a60) - john@winterfellstarks.com (0x15d4bd30)
1: null (0x3b864a60) - lordsnow@nightswatch.org (0x15f0f2d0)
2: null (0x3b864a60) - john.snow@gmail.com (0x15f3b470)
3: null (0x3b864a60) - jsnow@gmail.com (0x15d02060)
4: _$!<Work>!$_ (0x15f352d0) - john.snow@facebook.com (0x15f3d480)
5: _$!<Other>!$_ (0x15fbeae0) - john.snow@gmail.com (0x15f2a170)
6: _$!<Other>!$_ (0x15de9ce0) - jsnow@gmail.com (0x15f0f0e0)
7: _$!<Other>!$_ (0x15f0a110) - lordsnow@nightswatch.org (0x15f00830)
(lldb) po selectedIndex
2
(lldb) po identifier
2
(lldb) po selectedEmail
john.snow@gmail.com
Я бы очень признателен за помощь здесь.
1 ответ
К сожалению, это не тот ответ, который вы ищете.
У меня была эта проблема, но с номерами телефонов, а не по электронной почте. Та же проблема, хотя.
Я "исправил" это, отключив контакты (обе учетные записи - gmail и icloud), а затем снова включив их. Как только это произошло, и у них было немного времени для повторной ссылки, все работало нормально.
Я думаю, что это была поврежденная адресная книга, но, конечно, нет доказательств:(