2012-11-30 54 views

回答

9

我有这个同样的问题,当我在WWDC这一年,我问了好几个苹果的工程师和他们没有任何线索。我问了一个我认识的人,他有回答:

event.organizer.URL.resourceSpecifier 

这适用于任何EKParticipant。我被告诫不要使用描述字段,因为这可能随时改变。

希望这会有所帮助!

+0

的最佳解决方案 – Rakesh

+1

当EKParticipant主要是它不工作(的iOS 7.1) – ierceg

+0

它应该是'participant.URL.resourceSpecifier',但不只是'organizer'财产在EKEvent中,如'attendees'属性 – likid1412

1

该属性不会暴露给每个API版本6.0 - 我正在寻找答案,并没有发现任何其他工作,而不是从对象的描述中解析出电子邮件地址。例如:

EKParticipant *organizer = myEKEvent.organizer 
NSString *organizerDescription = [organizer description]; 
//(id) $18 = 0x21064740 EKOrganizer <0x2108c910> {UUID = D3E9AAAE-F823-4236-B0B8-6BC500AA642E; name = Hung Tran; email = [email protected]; isSelf = 0} 

分析上面的字符串转换成一个NSDictionary的关键@“电子邮件”

3

以上解决方案是可靠的:

  1. URL可能类似于/xyzxyzxyzxyz.../principal,显然这不是一个电子邮件。
  2. EKParticipant:description可能会更改,不包括电子邮件了。
  3. 您可以将emailAddress选择器发送给该实例,但这是未记录的,可能会在将来发生变化,同时可能会导致您的应用程序被拒登。

所以最后你需要做的是使用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

为EKParticipant
+0

嗨!我尝试使用你的代码,但记录变量总是零在我的情况。该网址与您所提到的一样(以委托人结尾)。我在文档中发现,如果未找到参与者,则返回nil。但我查了我的地址簿和日历,它存在(所以应该找到它)。任何想法为什么ABRecordWithAddressBook:会返回零? – haluzak

+0

@haluzak不知道,对不起。这个API非常糟糕。我认为我们最终决定将无文档的'emailAddress'选择器发送到实例。 – ierceg

+0

最后我想到了,我没有访问地址簿的权限,所以在使用您提供的代码之前,您必须请求访问权限。否则它运作良好,谢谢!但我同意API非常糟糕,几乎无法使用。 – haluzak

2

类别:

import Foundation 
import EventKit 
import Contacts 

extension EKParticipant { 
    var email: String? { 
     // Try to get email from inner property 
     if respondsToSelector(Selector("emailAddress")), let email = valueForKey("emailAddress") as? String { 
      return email 
     } 

     // Getting info from description 
     let emailComponents = description.componentsSeparatedByString("email = ") 
     if emailComponents.count > 1 { 
      let email = emailComponents[1].componentsSeparatedByString(";")[0] 
      return email 
     } 

     // Getting email from contact 
     if let contact = (try? CNContactStore().unifiedContactsMatchingPredicate(contactPredicate, keysToFetch: [CNContactEmailAddressesKey]))?.first, 
      let email = contact.emailAddresses.first?.value as? String { 
      return email 
     } 

     // Getting email from URL 
     if let email = URL.resourceSpecifier where !email.hasPrefix("/") { 
      return email 
     } 

     return nil 
    } 
}