Setting alarms for calendar events

Setting alarms for calendar events

Learn how to add an alarm to an event that notify users before an event starts.

One of the features of the EventKit framework is to provide users with the option to set alarms for their calendar items. Alarms are defined by the class EKAlarm and appear as notifications, reminding users of scheduled calendar events.

The alarm trigger can be time-based or geofenced, triggering at a specific time, relative to a time offset, or when the person enters or exits a geographic region.

On macOS 10.8 or later, you can set up actions that occur when the alarm triggers, such as playing a sound or sending an email, by setting the type property of EKAlarm.

Since an alarm is added to an existing event, you need to be able to access the user's events.


One of the best moments to associate an alarm with an event is when creating a new event. You can make a time-based alarm by using the init(absoluteDate:) or the init(relativeOffset:) initializers.

The initializer with a relative offset allows you to define how many seconds before or after the event starts you want the alarm to trigger. A negative value represents before and a positive value after.

let alarm = EKAlarm(relativeOffset: TimeInterval(-600))

To associate the alarm with a calendar event, use the addAlarm(_:) method. An event can have multiple alarms associated with it and they can be accessed over the alarms property.

event.addAlarm(alarm)

Here is an example of how you can set up an alarm when creating a new event in your application:

import EventKit
import Observation

@Observable
final class CalendarEventManager {

    let eventStore = EKEventStore()
    
    func createEvent(
        title: String,
        startDate: Date,
        endDate: Date,
        alarmLeadMinutes: Int = 10
    ) async {
        // Ensure we have a calendar to save into (user's default for new events).
        guard let targetCalendar = eventStore.defaultCalendarForNewEvents else {
            print("No default calendar available for new events.")
            return
        }
        
        // Create the event and set its primary fields.
        let event = EKEvent(eventStore: eventStore)
        event.title = title
        event.startDate = startDate
        event.endDate = endDate
        event.calendar = targetCalendar
        
        // Configure a relative alarm that fires N minutes *before* the start.
        // Negative offset = before startDate; positive = after.
        let alarmOffset = TimeInterval(-alarmLeadMinutes * 60)
        let alarm = EKAlarm(relativeOffset: alarmOffset)
        event.addAlarm(alarm)
        
        do {
            try eventStore.save(event, span: .thisEvent)
            print("Event with alarm was saved.")
        } catch {
            print("Failed to save event: \(error.localizedDescription)")
        }
    }
    
}