我正在努力解决iOS 16.4下的EventKit问题。这个问题只出现在我的iPhone上,而不是在模拟器上,尽管两者运行的是同一版本的iOS。在第一步中,我创建一个日历事件,如下所示:
eventStore.requestAccess(to: .event, completion: { granted, _ in
if granted == false {
return
}
if let calendarForEvent =
eventStore.calendar(withIdentifier: calendar) {
let event = EKEvent(eventStore: eventStore)
event.calendar = calendarForEvent
event.title = "SweatPlan: (workout.viewTitle)"
event.startDate = workout.viewStart
event.endDate = workout.viewEnd
do {
try eventStore.save(event, span: .thisEvent, commit: true)
} catch let error {
fatalError(error.localizedDescription)
}
print("New Event: (event.eventIdentifier)")
completion(event.eventIdentifier ?? "")
}
})
这工作得很好,输出类似New Event: Optional("744E067A-E94B-49BD-86F4-1345365D5B37:66EF8CCB9CB64F88867D6BA6F3670D470.32 ")
的内容现在我尝试检索和更新这个事件,如下所示:
eventStore.requestAccess(to: .event, completion: { granted, _ in
if granted == false {
return
}
if workout.calendarEventId == nil {
return
}
print("Updating Event: (workout.calendarEventId)")
if let event = eventStore.event(withIdentifier: workout.calendarEventId!) {
event.title = "SweatPlan: (workout.viewTitle)"
event.startDate = workout.viewStart
event.endDate = workout.viewEnd
do {
try eventStore.save(event, span: .thisEvent, commit: true)
} catch let error {
print(error.localizedDescription)
}
}
})
即使这段代码输出Updating Event: Optional("744E067A-E94B-49BD-86F4-1345365D5B37:66EF8CCB9CB64F88867D6BA6F3670D470.32 ")
——很明显事件标识符被正确传递——我得到以下错误消息:
[EventKit]获取标识符为744E067A-E94B-49BD-86F4-1345365D5B37:66EF8CCB9CB64F88867D6BA6F3670D470.32的事件错误:错误域=EKCADErrorDomain Code=1010 "Object not found。它可能已被删除。UserInfo={NSLocalizedDescription=对象未找到。}
就上下文而言,我使用的日历来自Exchange帐户,而不是本地iOS本地/iCloud日历。
为了确定问题的原因,我迭代了日历中的所有事件,发现我创建的事件具有不同的事件标识符Optional("744E067A-E94B-49BD-86F4-1345365D5B37:040000008200E00074C5B7101A82E0080000000010BAFC68D36BD90100000000000000001000000045FD649C85DE1A4383C646B8724BCEBE")
。事实上,我发现这个日历中所有事件标识符的格式与我最初创建事件时获得的标识符的格式不同。
我的问题是:
- 为什么创建的事件标识符在保存后会改变?
- 我如何能够检索正确的事件标识符来更新/删除事件之后?
这让人心烦。我也面临同样的问题。它在iOS 15.7, iOS 16.2和iOS 16.6上正常工作,但在16.4上不正常🤯
我发现(下面的日志)的顺序是
- 点击按钮保存事件
- 事件以id
A
保存 .EKEventStoreChanged
被触发eventIdentifier
还是一样-A
- ~ 2-3秒后,另一个
.EKEventStoreChanged
被触发 - 现在
eventIdentifier
已更改
08:38:01.491330+0200 Saved with eventIdentifier: 152EE5BB-00A6-4C19-8D07-F9CE7BD386BE:4F8A6AE5E1AD4183B781959B272D08E90.32
08:38:01.492764+0200 .EKEventStoreChanged notification, eventIdentifier is the same
08:38:04.400813+0200 .EKEventStoreChanged notification, eventIdentifier changed
08:38:04.412976+0200 Manually found the event 152EE5BB-00A6-4C19-8D07-F9CE7BD386BE:040000008200E00074C5B7101A82E00800000000E711F73DC2B3D90100000000000000001000000012093959E838144BA48F186259DB8142
我们可以注意到两个事件的eventIdentifier
都以152EE5BB-00A6-4C19-8D07-F9CE7BD386BE
开头,但这并没有真正的帮助-因为其他添加的事件也以这个id开头。
由于我们知道事件的开始时间和标题(可能还有注释),我们可以尝试通过过滤日历事件来查找事件。
let datePredicate = eventStore.predicateForEvents(
withStart: startDate,
end: startDate.addingTimeInterval(eventDuration),
calendars: nil
)
let events = eventStore.events(matching: datePredicate)
let filteredEvents = events.filter {
$0.title == title &&
$0.notes == notes // beware that the the spaces/newlines might be different after event has been added to the calendar - so you should address that somehow
}
// do something with `filteredEvents` - i.e. check if there's only one, update your local storage base on this, etc.
我讨厌它,但这是我唯一能让它工作的方法🤷