Swift中通过eventId获取日历事件失败问题排查
问题:通过eventIdentifier获取日历事件返回nil,重启App后ID失效
问题概述
在CalendarEventsManager单例类中,日历权限已配置且正常工作。保存事件时能成功打印event.eventIdentifier,但后续用该ID调用eventStore.event(withIdentifier:)获取事件时返回nil。尝试使用calendarItemIdentifier结果相同,且App保持打开状态时ID有效,重启后所有事件标识符似乎都发生了变化。
保存事件的代码片段
import SwiftUI import EventKit final class CalendarEventsManager { static let shared = CalendarEventsManager() let eventStore = EKEventStore() // 此处省略定义事件属性的更多代码 do { try CalendarEventsManager.shared.eventStore.save(event, span: .thisEvent) print("Event saved on calendar, with eventId: \(event.eventIdentifier ?? "")") } catch { print("Error saving event: \(error)") }
获取事件的代码片段
if let event = CalendarEventsManager.shared.eventStore.event(withIdentifier: eventId ?? "") { print("EventID: \(event.eventIdentifier ?? "")") // <- 此处为Nil } }
更新内容(2023年11月12日 18:05)
App未关闭时获取事件正常,但重启App后所有事件标识符均失效。以下是完整的CalendarEventsManager类代码:
import SwiftUI import EventKit /// 负责在添加、更新或删除应用排练时管理系统日历事件的增删操作。 final class CalendarEventsManager { @AppStorage("savingsCalendar") var savingsCalendar = "" @AppStorage("rehearsalsDuration") var rehearsalsDuration = 900 @AppStorage("eventsAlarmsOn") var eventsAlarmsOn = false @AppStorage("eventsAlarmsTime") var eventsAlarmsTime = 900 // 单例模式确保全App使用同一个EKEventStore实例,个人认为并非必需。 static let shared = CalendarEventsManager() static let eventStore = EKEventStore() /// 从`Rehearsal`向系统日历添加事件。 /// - Parameter rehearsal: 关联的`Rehearsal`对象。 func createEvent(from rehearsal: Rehearsal) { let event = EKEvent(eventStore: CalendarEventsManager.eventStore) event.title = NSLocalizedString("Rehearsal with ", comment: "") + (rehearsal.relatedStudent?.name)! + " (" + (rehearsal.relatedStudent?.relatedInstrument?.name)! + ")" event.startDate = rehearsal.date event.endDate = rehearsal.date?.addingTimeInterval(TimeInterval(rehearsalsDuration)) if eventsAlarmsOn { let time = Double(eventsAlarmsTime) let alarm = EKAlarm(relativeOffset: -time) event.alarms = [alarm] } var worksInfo: String = "" var relatedWorks = [Work]() if rehearsal.relatedWorks?.count ?? 0 > 0 { for work in Array(rehearsal.relatedWorks as! Set<Work>) { relatedWorks.append(work) } worksInfo.append(relatedWorks.map{ "\($0.relatedComposer?.name ?? ""): \($0.title ?? "")"}.joined(separator: "\r")) } let notes = (rehearsal.notes.nilIfEmpty != nil) ? rehearsal.notes ?? "" : "" let publicInfo = rehearsal.inPublic ? NSLocalizedString("Public", comment: "") : "" let footText = NSLocalizedString("This is a copy of a CompingApp rehearsal. Any changes will not take any effect on app data.", comment: "") event.notes = "\(worksInfo)\r\(notes)\r\(publicInfo)\r---\r\(footText)" event.calendar = CalendarEventsManager.eventStore.calendar(withIdentifier: savingsCalendar) do { try CalendarEventsManager.eventStore.save(event, span: .thisEvent) } catch { print("Error saving event: \(error)") } /// 使用calendarItemIdentifier,因eventIdentifier似乎不可靠,但该值仍会变化。 rehearsal.setValue(event.calendarItemIdentifier, forKey: "eventId") } /// 删除与`Rehearsal`关联的系统日历事件。 /// - Parameter rehearsal: 关联的`Rehearsal`对象。 func deleteEvent(for rehearsal: Rehearsal) { if let event = CalendarEventsManager.eventStore.calendarItem(withIdentifier: rehearsal.eventId ?? "") { do { try CalendarEventsManager.eventStore.remove(event as! EKEvent, span: .thisEvent, commit: true) } catch { print("Error deleting event: \(error)") } } } }
内容的提问来源于stack exchange,提问作者arroyot24
相关产品推荐
相关产品推荐

