ABMultilValueGetIndexForIdentifier devuelve un índice incorrecto cuando el contacto tiene LinkedContacts

Noté un error en la lógica que usamos para manejar la selección de un correo electrónico específico para un contacto presentado por un ABPeoplePickerNavigationController. El error ocurre específicamente cuando el contacto tiene Contactos Vinculados, desde Twitter o Facebook.

He comprobado nuestra lógica en varias preguntas relacionadas con StackOverflow y parece que estoy haciendo todo "correctamente":

  • iOS Obtener la dirección de correo electrónico de los contactos seleccionados en la matriz
  • ¿Cómo recibir un correo electrónico usando ABPeoplePicker?
  • ¿Cómo obtengo una dirección de correo electrónico seleccionada por el usuario de ABPeoplePicker?

Aquí está el código para cargar el ABPeoplePicker después de que se toca un button:

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

Más tarde, cuando un usuario toca un correo electrónico para un contacto seleccionado, lo manejamos de la siguiente manera:

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

Esto funciona perfectamente cuando el contacto no tiene ningún contacto vinculado, por ejemplo, Facebook; sin embargo, cuando lo hace, la dirección de correo electrónico impresa aquí no será la elegida por el usuario.

Por ejemplo, tengo un amigo en mis contactos al que llamaremos John Snow , somos buenos amigos, así que estoy conectado con él en iCloud, 2 counts de Gmail diferentes y Facebook.

Cuando navego a la página de contacto de John Snow, veo los siguientes 5 correos electrónicos:

  • john.snow@gmail.com
  • jsnow@gmail.com
  • lordsnow@nightswatch.org
  • john.snow@facebook.com
  • john@winterfellstarks.com

Además de celdas para cada uno de los contactos vinculados.

Entonces, si presiono lordsnow@nightswatch.org (índice de 2 en la list de correos electrónicos presentados) y tengo un punto de interrupción establecido dentro de la opción shouldContinueAfterSelecting callback en el NSLog e imprime las variables relevantes, esto es lo que veré:

 (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 

Realmente agradecería un poco de ayuda aquí.

Lamentablemente, esta no es la respuesta que está buscando.

Tuve este problema, pero con los numbers de teléfono, no el correo electrónico. El mismo problema.

Lo "solucioné" deshabilitando los contactos (ambas counts – gmail y icloud) y volviéndolos a encender de nuevo. Una vez que eso sucedió, y tuvieron un poco de time para volver a vincular, funcionó bien.

Creo que fue una libreta de direcciones corrupta, pero, por supuesto, no hay testings 🙁