EventKit fails to find previously created event using eventIdentifier (iOS 16.4)

200 Views Asked by At

I'm struggling with an issue in EventKit under iOS 16.4. This issue only appears on my iPhone, not in the simulator, although both are running the same version of iOS. In the first step, I create a calendar event like this:

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 ?? "")
    }
})

This works fine and outputs something like New Event: Optional("744E067A-E94B-49BD-86F4-1345365D5B37:66EF8CCB9CB64F88867D6BA6F3670D470.32\0")

Now I try to retrieve and update this event as follows:

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)
        }
    }
})

Even though this code outputs Updating Event: Optional("744E067A-E94B-49BD-86F4-1345365D5B37:66EF8CCB9CB64F88867D6BA6F3670D470.32\0") - so clearly the event identifier was passed correctly - I get the following error message:

[EventKit] Error getting event with identifier 744E067A-E94B-49BD-86F4-1345365D5B37:66EF8CCB9CB64F88867D6BA6F3670D470.32: Error Domain=EKCADErrorDomain Code=1010 "Object not found. It may have been deleted." UserInfo={NSLocalizedDescription=Object not found. It may have been deleted.}

For context, the calendar I am using for this is from an Exchange account and not a native iOS local / iCloud calendar.

To identify the cause of the issue, I iterated over all events in the calendar and found that the event I created has been found with a different event identifier of Optional("744E067A-E94B-49BD-86F4-1345365D5B37:040000008200E00074C5B7101A82E0080000000010BAFC68D36BD90100000000000000001000000045FD649C85DE1A4383C646B8724BCEBE"). In fact I have found that the format of all the event identifiers in this calendar are different in format from the identifier I get when initially creating the event.

So my questions are:

  1. Why would the event identifier on a created event change after saving?
  2. How would I be able to retrieve the correct event identifier to update / delete the event afterwards?
1

There are 1 best solutions below

1
Michal Šrůtek On

This is upsetting. I'm facing the same problem. It is working as expected on iOS 15.7, iOS 16.2 and iOS 16.6, but not on 16.4

What I've discovered (logs below) is that the order is

  • I tap a button to save the event
  • The event gets saved with id A
  • .EKEventStoreChanged is fired
  • The eventIdentifier is still the same - A
  • ~ 2-3 seconds pass and another .EKEventStoreChanged is fired
  • Now the eventIdentifier has changed
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

We can notice that both events' eventIdentifier starts with 152EE5BB-00A6-4C19-8D07-F9CE7BD386BE, but that's not really helpful - as other added events also start with this id.

Since we know the start time of the event and the title (and possibly notes), we can try to find the event by filtering the calendar events.

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.

I hate it, but it's the only way I was able to make it work