ABPeoplePickerNavigationController によって提示された連絡先の特定の電子メールの選択を処理するために使用するロジックにバグがあることに気付きました。このバグは、連絡先が Twitter または Facebook からリンクされた連絡先を持っている場合に特に発生します。
関連するいくつかの StackOverflow の質問に対してロジックを再確認しましたが、すべて「正しく」実行しているようです。
- 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 などの連絡先がリンクされていない場合は完全に機能しますが、リンクされている場合、ここに出力される電子メール アドレスはユーザーが選択したものではありません。
たとえば、連絡先にJohn Snowという友人がいて、私たちは仲が良いので、iCloud、2 つの異なる Gmail アカウント、および Facebook で彼とつながっています。
John Snow の連絡先ページに移動すると、次の 5 つのメールが表示されます。
- john.snow@gmail.com
- jsnow@gmail.com
- lordsnow@nightswatch.org
- john.snow@facebook.com
- john@winterfellstarks.com
リンクされた各連絡先のセルと同様に。
したがって、lordsnow@nightswatch.org (提示された電子メールのリストの 2 のインデックス)をタップし、NSLog の shouldContinueAfterSelecting コールバック内にブレークポイントを設定して、関連する変数を出力すると、次のように表示されます。
(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
ここで助けていただければ幸いです。