TN3130: Changes to EventKit in macOS Ventura 13
Test your apps against EventKit API changes in macOS Ventura 13.
Overview
In macOS Ventura 13, the EventKit framework has seen significant changes. This document highlights some of the notable changes. To learn about related changes in iOS 16, see TN3132: Changes to EventKit and EventKitUI in iOS 16.
For apps running on systems prior to macOS Ventura 13, the legacy behavior remains in place when using EventKit. When you run your app on macOS Ventura 13, and have built it with Xcode 14 and linked against the macOS 13 SDK, you may see behavior that you are unfamiliar with when using EventKit. To identify these changes in behavior, thoroughly test your app for each major OS version it supports. Confirm that your implementation of EventKit behaves as you expect in each OS version and update your code where needed. If you notice an unexpected behavior in EventKit, report it using Feedback Assistant.
EKCalendar
The inherited initializer init() throws an exception when attempting to create a new calendar. Use init(for:eventStore:) instead.
let calendar = EKCalendar(for: .event, eventStore: eventStore)In the legacy behavior, this inherited initializer returns an unusable EKCalendar object.
EKCalendarItem
Fetching recurrence rules
The recurrenceRules property returns an empty array if the calendar item doesn’t have any recurrence rules.
In the legacy behavior, recurrenceRules returns nil if the calendar item doesn’t have any recurrence rules.
Updating time zones
Changing the time zone of an event no longer changes the absolute time at which it occurs.
EKEvent
Creating events
The inherited initializer init() throws an exception when attempting to create a new event. Use init(eventStore:) to create new events.
In the legacy behavior, this inherited initializer returns an unusable EKEvent object.
Event identifiers
The eventIdentifier property now returns identifiers in a new format. The previous identifier format will continue to work.
End date of all-day events
The endDate property of all-day events returns a time of 11:59:59 PM on the last day of this event.
Event title: Marathon
Start date: June 18, 2022 at 12:00:00 AM PDT
End date: June 18, 2022 at 11:59:59 PM PDTIn the legacy behavior, this property returns a time of 12:00:00 AM on the day after the event.
Event title: Marathon
Start date: June 18, 2022 at 12:00:00 AM PDT
End date: June 19, 2022 at 12:00:00 AM PDTEKEventStore
Accessing sources
The sources property now contains delegate sources.
// Fetch all sources associated with the event store.
let sources = eventStore.sources
sources.forEach { source in
// Let's check whether source is a delegate event source.
let name = (source.isDelegate) ? "Delegate Source" : "Source"
print("\(name): \(source.title)")
}
// Prints "Source: iCloud"
// Prints "Delegate Source: Calculus Office Hours"Fetching events
events(matching:) and enumerateEvents(matching:using:) no longer necessarily return events sorted by start date.
Accessing calendar events
The calendarItem(withIdentifier:), calendarItems(withExternalIdentifier:), and event(withIdentifier:) methods may return different occurrences of an event or reminder with a given identifier in some cases. For instance, when the first occurrence of a recurring event was modified and the specified identifier refers to this occurrence. In this case, use the given identifier to fetch the unmodified version of the event’s first occurrence.
Committing changes
When you call saveCalendar(_:commit:), removeCalendar(_:commit:), save(_:span:commit:), remove(_:span:commit:), save(_:commit:), or remove(_:commit:) methods with the commit parameter set to true, EKEventStore attempts to immediately save and commit your changes to the event store. If the commit fails, EKEventStore automatically rolls back all changes that been saved but aren’t yet committed to the event store.
In the legacy behavior, uncommitted objects remain saved in the event store.
EKReminder
The inherited initializer init() throws an exception when attempting to create a new reminder. Use init(eventStore:) instead.
let reminder = EKReminder(eventStore: eventStore)In the legacy behavior, this inherited initializer returns an unusable EKReminder object.
EKSource
The isDelegate property indicates whether the source is an event source delegated to the user.
Revision History
2022-08-16 First published.
See Also
Latest
TN3205: Low-latency communication with RDMA over ThunderboltTN3206: Updating Apple Pay certificatesTN3179: Understanding local network privacyTN3190: USB audio device design considerationsTN3194: Handling account deletions and revoking tokens for Sign in with AppleTN3193: Managing the on-device foundation model’s context windowTN3115: Bluetooth State Restoration app relaunch rulesTN3192: Migrating your iPad app from the deprecated UIRequiresFullScreen keyTN3151: Choosing the right networking APITN3111: iOS Wi-Fi API overviewTN3191: IMAP extensions supported by Mail for iOS, iPadOS, and visionOSTN3134: Network Extension provider deploymentTN3189: Managing Mail background traffic loadTN3187: Migrating to the UIKit scene-based life cycleTN3188: Troubleshooting In-App Purchases availability in the App Store