Доступ к электронной почте в EKParticipant/EKATtendee

Я хочу получить адрес электронной почты участника мероприятия в EKEventKit.

У меня есть следующий код:

if ( event.attendees.count > 0)
{
    NSArray *people = event.attendees;
    for(EKParticipant *person in people)
    {
        if ( person.participantType == EKParticipantTypePerson && person.URL.resourceSpecifier.length > 0)
        {
            NSString *dataString = [NSString stringWithFormat:@"event_id=%ld&name=%@&is_me=%d&email=%@&role=%@",event_id,person.name, person.isCurrentUser,person.URL.resourceSpecifier, @"attendee"];
            //<DO SOMETHING USEFUL WITH dataString>;
        }
    }
}

Когда я запускаю код, человек заполняет следующие данные:

EKAttendee <0x17809acc0> {UUID = 4F657EA4-452A-412B-A9AA-FEC5551DC096; name = A. Real Person; email = [email protected]; status = 0; role = 0; type = 1}

Как получить доступ к полю электронной почты?

Я пытался (как указано выше) использовать URL.resourceSpecifier, но часто это какая-то странная строка, которая определенно НЕ является адресом электронной почты.


person SchroedingersCat    schedule 13.08.2014    source источник


Ответы (3)


«Описание» объекта EKParticipant представляет собой своего рода список свойств. Я безуспешно пробовал несколько различных методов анализа этого списка во что-то, содержащее пары ключ: значение. Поэтому я написал следующее:

                            // This is re-useable code that converts any class description field into a dictionary that can be parsed for info
                    NSMutableDictionary *descriptionData = [NSMutableDictionary dictionary];
                    for (NSString *pairString in [person.description componentsSeparatedByString:@";"])
                    {
                        NSArray *pair = [pairString componentsSeparatedByString:@"="];
                        if ( [pair count] != 2)
                            continue;
                        [descriptionData setObject:[[pair objectAtIndex:1] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] forKey:[[pair objectAtIndex:0]stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]];
                    }

При этом я просто получаю адрес электронной почты с

    [descriptionData valueForKey:@"email"]
person SchroedingersCat    schedule 13.08.2014
comment
Он работает, как и ожидалось, я столкнулся с проблемой в iOS 12 и не смог получить поле электронной почты, ваш код сработал для меня. - person GvSharma; 24.09.2018

Я попытался ответить на этот же вопрос в "как получить электронную почту ekevent EKparticipant?" нить:

Что вам нужно сделать, это использовать EKPrincipal:ABRecordWithAddressBook, а затем извлечь электронную почту оттуда. Так:

NSString *email = nil;
ABAddressBookRef book = ABAddressBookCreateWithOptions(nil, nil);
ABRecordRef record = [self.appleParticipant ABRecordWithAddressBook:book];
if (record) {
    ABMultiValueRef value = ABRecordCopyValue(record, kABPersonEmailProperty);
    if (value
        && ABMultiValueGetCount(value) > 0) {
        email = (__bridge id)ABMultiValueCopyValueAtIndex(value, 0);
    }
}

Обратите внимание, что вызов ABAddressBookCreateWithOptions стоит дорого, поэтому вы можете сделать это только один раз за сеанс.

Если вы не можете получить доступ к записи, вернитесь к URL.resourceSpecifier.

person ierceg    schedule 13.09.2014
comment
хороший ответ, но когда участника нет в адресной книге iPhone, эта запись будет нулевой. - person frank; 17.08.2015
comment
@frank Спасибо. Да это вообще ненадежный API. Я думаю, мы наконец решили отправить селектор emailAddress (недокументированный) в appleParticipant. - person ierceg; 20.08.2015
comment
@frank Это не должно быть опасно (потеря данных, сбои и т. д.), но это определенно грязная техника. - person ierceg; 21.08.2015

В Свифт 4:

private static func getParticipantDescriptionData(_ participant: EKParticipant) -> [String:String] {
  var descriptionData = [String: String]()
  for pairString in participant.description.components(separatedBy: ";") {
    let pair = pairString.components(separatedBy: "=")
    if pair.count != 2 {
      continue
    }
    descriptionData[pair[0].trimmingCharacters(in: .whitespacesAndNewlines)] =
      pair[1].trimmingCharacters(in: .whitespacesAndNewlines)
  }
  return descriptionData
}
person tezqa    schedule 03.07.2018