如何修复iCalendar事件保存时的EKErrorDomain Code=11及重复事件问题
修复iCalendar事件插入的EKErrorDomain Code=11错误及重复事件问题
我来帮你搞定这两个问题!先拆解下错误根源,再给你修复后的完整代码:
问题原因分析
1. EKErrorDomain Code=11(对象属于不同存储)错误
这个错误的核心是你在循环里直接复用了events数组里的现有EKEvent对象——这些对象可能已经属于另一个事件存储实例,或者绑定到了不属于当前store的日历上。当你尝试修改并保存这些"外来"对象时,系统就会抛出"对象属于不同存储"的错误。
2. 重复事件问题
你的双层循环逻辑有问题:外层遍历现有events,内层遍历假日列表,只要某个现有事件和当前假日不匹配,就插入一次假日。这会导致同一个假日被多次插入(比如现有10个事件,假日和其中9个不匹配,就会插入9次)。而且你的重复判断逻辑也不对,应该是检查假日是否已经存在于日历中,而不是拿现有事件逐个对比。
修复方案&优化后的代码
// 先封装一个方法,检查某个假日是否已经存在于目标日历中 func isHolidayExists(holiday: Holiday, in store: EKEventStore) -> Bool { guard let startDate = holiday.start?.date, let endDate = holiday.end?.date, let summary = holiday.summary, let targetCalendar = store.defaultCalendarForNewEvents else { return false } // 创建查询谓词,匹配日期范围和目标日历 let predicate = store.predicateForEvents(withStart: startDate, end: endDate, calendars: [targetCalendar]) let existingEvents = store.events(matching: predicate) // 检查是否有相同标题的事件存在 return existingEvents.contains { $0.title == summary } } // 处理假日插入的主逻辑 for holiday in holidayArray ?? [] { // 先检查当前假日是否已经存在,存在则跳过 guard !isHolidayExists(holiday: holiday, in: eventStore) else { print("\(holiday.summary ?? "Unknown") 已存在于日历中,跳过") continue } // 校验假日数据完整性,避免强制解包崩溃 guard let startDate = holiday.start?.date, let endDate = holiday.end?.date, let summary = holiday.summary, let targetCalendar = eventStore.defaultCalendarForNewEvents else { print("假日数据不完整,跳过本次插入") continue } // 创建全新的EKEvent实例,关联当前的eventStore let newEvent = EKEvent(eventStore: eventStore) newEvent.title = summary newEvent.startDate = startDate newEvent.endDate = endDate newEvent.calendar = targetCalendar // 保存事件 do { try eventStore.save(newEvent, span: .thisEvent) print("✅ 成功保存事件:\(summary)") } catch let error as NSError { print("❌ 保存事件失败:\(error.localizedDescription),错误码:\(error.code)") } }
关键优化点说明
- 彻底解决Code=11错误:每次创建全新的
EKEvent实例,并明确关联当前的eventStore,避免复用"外来"事件对象。 - 精准的重复检查:通过
EKEventStore的官方查询API直接查找是否存在相同日期和标题的事件,比双层循环高效且准确。 - 安全的可选值处理:用
guard let做可选绑定,彻底避免强制解包!导致的崩溃问题。 - 简化逻辑结构:直接遍历假日列表,逐个检查并插入,代码逻辑更清晰易懂。
内容的提问来源于stack exchange,提问作者Ricardo Milos
相关产品推荐
相关产品推荐

