Skip to content

EventKit & Contacts

Four skills covering calendar events, reminders, and contact access for iOS. Built around the permission models that changed significantly in iOS 17 (EventKit) and iOS 18 (Contacts).

Skills in This Suite

SkillTypeWhat It Covers
axiom-eventkitDisciplineAccess tier decision tree, permission model, EventKitUI patterns, reminder patterns, store lifecycle, migration, pressure scenarios
axiom-eventkit-refReferenceEKEventStore, EKEvent, EKReminder, EKAlarm, EKRecurrenceRule, EventKitUI controllers, Siri Event Suggestions, virtual conference extensions, error codes
axiom-contactsDisciplineAccess level decision tree, Contact Access Button, picker vs store decisions, key fetching discipline, ContactProvider, pressure scenarios
axiom-contacts-refReferenceCNContactStore, CNMutableContact, CNSaveRequest, CNContactFormatter, ContactsUI, ContactProvider, change history sync, error codes

When to Use

EventKit skills when you're:

  • Adding events to the user's calendar
  • Creating or managing reminders
  • Choosing between EventKitUI, write-only, or full access
  • Migrating from pre-iOS 17 permission APIs
  • Implementing Siri Event Suggestions or virtual conference extensions

Contacts skills when you're:

  • Reading or writing contacts
  • Choosing between picker, Contact Access Button, or full store access
  • Implementing contact search or selection UIs
  • Migrating to iOS 18 limited access
  • Building a Contact Provider extension

Example Prompts

  • "How do I add an event to the user's calendar?"
  • "What's the difference between write-only and full Calendar access?"
  • "How do I create reminders programmatically?"
  • "How do I let users pick a contact in SwiftUI?"
  • "What's the Contact Access Button and when should I use it?"
  • "How do I implement Siri Event Suggestions for restaurant reservations?"
  • "How do I handle iOS 18 limited contact access?"
  • "How do I detect contact changes for sync?"

Key Concepts

EventKit: Three Access Tiers

Most apps only need Tier 1 — zero permission prompts.

TierMethodUse Case
No accessEKEventEditViewControllerAdd single events via system UI (iOS 17+ out-of-process)
No accessSiri Event SuggestionsReservation-style events (restaurant, flight, hotel)
Write-onlyrequestWriteOnlyAccessToEvents()Custom UI, batch saves, silent creation
Full accessrequestFullAccessToEvents()Read, modify, delete existing events
Full accessrequestFullAccessToReminders()All reminder operations (no write-only tier)

Contacts: Four Authorization Levels

Most apps should use Contact Access Button or CNContactPickerViewController — no authorization needed.

LevelBehavior
Not DeterminedContactAccessButton works — auto-triggers simplified prompt on tap
Limited (iOS 18+)App sees only user-selected contacts. Same API surface, different visibility.
FullRead/write all contacts. Reserve for apps where contacts are the core feature.
DeniedNo access to contact data.

Key Pattern: Adding a Calendar Event (Zero Permissions)

swift
let store = EKEventStore()
let event = EKEvent(eventStore: store)
event.title = "Team Standup"
event.startDate = startDate
event.endDate = Calendar.current.date(byAdding: .hour, value: 1, to: startDate) ?? startDate

let editVC = EKEventEditViewController()
editVC.event = event
editVC.eventStore = store
editVC.editViewDelegate = self
present(editVC, animated: true)  // No permission prompt needed

Key Pattern: Contact Access Button (iOS 18+)

swift
ContactAccessButton(queryString: searchText) { identifiers in
    let contacts = await fetchContacts(withIdentifiers: identifiers)
}

Common Mistakes

MistakeCostFix
Requesting full Calendar access for "add to calendar"30%+ denial rateUse EventKitUI (zero permissions)
Calling deprecated requestAccess(to:) on iOS 17Throws error, no promptUse requestFullAccessToEvents()
Missing Info.plist key on iOS 17+Silent denialAdd NSCalendarsFullAccessUsageDescription
Accessing unfetched key on CNContactCrashAlways specify keysToFetch
Using CNContactStore for one-time pickingUnnecessary permission promptUse CNContactPickerViewController
Ignoring .limited contact status"Missing contacts" bugShow ContactAccessButton

Resources

WWDC: 2023-10052, 2024-10121, 2020-10197

Docs: /eventkit, /eventkitui, /contacts, /contactsui, /contactprovider, /technotes/tn3152, /technotes/tn3153, /technotes/tn3149

Released under the MIT License