CtrlK
BlogDocsLog inGet started
Tessl Logo

thiennc-tesoglobal/ios-skills

Community-maintained Agent Skills for complete Swift and Apple-platform app delivery.

73

Quality

92%

Does it follow best practices?

Run evals on this skill

Adds up to 20 points to the overall score

View guide

SecuritybySnyk

Medium

Suggest reviewing before use

Overview
Quality
Evals
Security
Files

SKILL.mdskills/eventkit/

name:
eventkit
description:
Creates, reads, edits, and presents calendar events or reminders with EventKit and EventKitUI. Use for authorization, event/reminder CRUD, calendars, recurrence, alarms, change observation, event editors, viewers, calendar choosers, or SwiftUI wrappers.

EventKit

Use EventKit for calendar and reminder authorization, CRUD, recurrence, alarms, and system editors.

Workflow

  1. Determine whether the app needs event write-only access, full event access, or reminder access and declare the matching usage descriptions.
  2. Retain one EKEventStore, request the narrowest authorization, and branch on current status.
  3. Create or fetch objects from that store, choose writable calendars, and make timezone/recurrence semantics explicit.
  4. Save or batch changes with the intended commit policy and surface recoverable errors.
  5. Observe store changes and verify denied/restricted access, recurrence edits, timezone changes, and external modifications.

Route by Task

  • Read core implementation details for authorization, events, reminders, recurrence, alarms, EventKitUI, and change observation.
  • Read extended EventKit patterns for SwiftUI wrappers, predicates, batch operations, and advanced recurrence workflows.

Core Decisions

  • Use current full-access/write-only authorization APIs rather than legacy generic access calls.
  • Never mix EKObject instances from different event stores.
  • Check calendar mutability before save and preserve explicit timezone intent.
  • Decide whether recurring edits affect one occurrence or the future span before saving.

Common Mistakes

DON'T: Use legacy requestAccess(to:) on current systems

// WRONG: Legacy request API on current systems
eventStore.requestAccess(to: .event) { granted, error in }

// CORRECT: Use the granular async methods
let granted = try await eventStore.requestFullAccessToEvents()

Keep it only in the compatibility fallback from Availability.

DON'T: Save events to a read-only calendar

// WRONG: No check -- will throw if calendar is read-only
event.calendar = someCalendar
try eventStore.save(event, span: .thisEvent)

// CORRECT: Verify the calendar allows modifications
guard someCalendar.allowsContentModifications else {
    event.calendar = eventStore.defaultCalendarForNewEvents
    return
}
event.calendar = someCalendar
try eventStore.save(event, span: .thisEvent)

DON'T: Ignore timezone when creating events

// WRONG: Event appears at wrong time for traveling users
event.startDate = Date()
event.endDate = Date().addingTimeInterval(3600)

// CORRECT: Set the timezone explicitly for location-specific events
event.timeZone = TimeZone(identifier: "America/New_York")
event.startDate = startDate
event.endDate = endDate

DON'T: Forget to commit batched saves

// WRONG: Changes never persisted
try eventStore.save(event1, span: .thisEvent, commit: false)
try eventStore.save(event2, span: .thisEvent, commit: false)
// Missing commit!

// CORRECT: Commit after batching
try eventStore.save(event1, span: .thisEvent, commit: false)
try eventStore.save(event2, span: .thisEvent, commit: false)
try eventStore.commit()

DON'T: Mix EKObjects from different event stores

// WRONG: Event fetched from storeA, saved to storeB
let event = storeA.event(withIdentifier: id)!
try storeB.save(event, span: .thisEvent) // Undefined behavior

// CORRECT: Use the same store throughout
let event = eventStore.event(withIdentifier: id)!
try eventStore.save(event, span: .thisEvent)

Review Checklist

  • Correct Info.plist usage description keys added for calendars and/or reminders
  • Authorization follows the version split in Availability
  • Write-only calendar access used only for direct event creation, not event/calendar reads
  • Authorization status checked before fetching or saving
  • Full access required before any event or reminder fetch
  • Single EKEventStore instance reused across the app
  • Events saved to a writable calendar (allowsContentModifications checked)
  • Recurring event saves specify correct EKSpan (.thisEvent vs .futureEvents)
  • Batched saves validate writable calendars, stage with commit: false, call throwing commit(), and on failure reset() unsaved state, discard every invalidated EKObject, then refetch or reconstruct before retry
  • EKEventStoreChanged notification observed to refresh stale data
  • Change observation uses the classic notification or guarded typed message per Availability
  • Timezone set explicitly for location-specific events
  • EKObjects not shared across different event store instances
  • EventKitUI delegates dismiss controllers in completion callbacks

References

skills

.mcp.json

README.md

tile.json