Swift开发:EKEvent的occurrenceDate与birthdayContactIdentifier问题求助
嘿,这两个问题我刚好有经验,来帮你捋清楚!
1. 通过birthdayContactIdentifier关联到对应联系人
要拿到这个标识符对应的联系人,你需要用到Contacts框架,步骤如下:
首先记得在项目里导入Contacts模块:
import Contacts
然后核心是用CNContactStore来查询联系人,不过必须先申请权限(否则会崩溃或拿不到数据):
let store = CNContactStore() // 请求联系人权限 store.requestAccess(for: .contacts) { granted, error in guard granted else { // 权限被拒绝,这里可以加提示用户开启权限的逻辑 return } // 权限通过后开始查询 if let contactId = get_event.birthdayContactIdentifier { // 指定需要获取的联系人属性,按需添加即可 let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey, CNContactPhoneNumbersKey] as [CNKeyDescriptor] do { let contact = try store.unifiedContact(withIdentifier: contactId, keysToFetch: keysToFetch) // 成功拿到联系人,这里可以做你需要的处理 print("联系人姓名:\(contact.givenName) \(contact.familyName)") } catch { print("查询联系人失败:\(error.localizedDescription)") } } }
注意:unifiedContact(withIdentifier:keysToFetch:)会返回苹果自动合并后的联系人(如果用户有重复的联系人条目),这是官方推荐的查询方式。另外必须指定要获取的属性,不能传空数组,否则会报错。
2. 解决occurrenceDate的时间显示问题与获取重复频率
关于occurrenceDate的时间偏差
你看到的2020-05-30 02:00:00 +0000是UTC标准时间,而你设置的是本地时间20:00-22:30,两者的差异完全是时区导致的。只需要把UTC时间转换成设备本地时区的时间即可:
if let occurrenceDate = get_event.occurrenceDate { // 转换成当前设备的本地时区 let localDate = occurrenceDate.convert(to: TimeZone.current) print("本地时间:\(localDate.description)") // 如果需要更友好的格式化显示,用DateFormatter let formatter = DateFormatter() formatter.dateStyle = .full formatter.timeStyle = .full formatter.timeZone = TimeZone.current print("格式化后的本地时间:\(formatter.string(from: localDate))") }
另外你提到输出了两个时间,建议检查下代码是否误把startDate和occurrenceDate一起打印了——occurrenceDate本身是单个重复实例的开始时间,正常只会输出一个时间。
获取重复频率与规则
要拿到事件的重复信息,直接看EKEvent的recurrenceRule属性,它包含了重复的频率、间隔、结束条件等关键信息:
if let recurrenceRule = get_event.recurrenceRule { // 判断重复频率 switch recurrenceRule.frequency { case .daily: print("每天重复") case .weekly: print("每周重复") case .monthly: print("每月重复") case .yearly: print("每年重复") @unknown default: print("未知重复频率") } // 重复间隔:比如间隔1是每周1次,间隔2是每两周1次 print("重复间隔:\(recurrenceRule.interval)") // 如果有重复结束日期,可以获取 if let endDate = recurrenceRule.endDate { print("重复结束日期:\(endDate)") } // 每周重复的话,还能拿到具体周几重复(1=周日,2=周一…7=周六) if recurrenceRule.frequency == .weekly { print("每周重复的星期:\(recurrenceRule.weekdays)") } }
补充:重复事件的startDate和endDate是第一个实例的时间,而occurrenceDate是当前你获取的这个重复实例的时间,两者可能不同哦。
内容的提问来源于stack exchange,提问作者user12616082
相关产品推荐
相关产品推荐

