After a long time researching every aspect of the code. I found that the problem is try eventStore.save(courseEvent, span: .futureEvents).
Alternatively, I use try eventStore.save(..., span: ..., commit: false) and eventStore.commit() to solve the problem.
I think this is caused by the data races because I'm using swift concurrency. While one event is saving, another one calls save method to save again, leading to data conflicts (just my guess.)
To solve this, luckily, we can commit a batch of events later using eventStore.commit() to avoid data conflicts. The result is what I expected !!🥳
And after that optimization, the performance of this function is up to 25% faster (exactly 136ms faster). (haha. Perfect.)
Final Code (in Swift 5.7):
func export_test() {
Task.detached {
await withTaskGroup(of: Void.self) { group in
for i in 0...15 {
group.addTask {
print("Task \(i): Start")
let courseEvent = EKEvent(eventStore: eventStore)
courseEvent.title = "TEST"
courseEvent.location = "TEST LOC"
courseEvent.startDate = .now
courseEvent.endDate = .now.addingTimeInterval(3600)
courseEvent.calendar = eventStore.defaultCalendarForNewEvents
courseEvent.addRecurrenceRule(EKRecurrenceRule(recurrenceWith: .daily, interval: 1, end: nil))
try eventStore.save(courseEvent, span: .futureEvents, commit: false)
}
}
}
eventStore.commit()
}
}