Build: swiftc calendar_dump.swift -o calendar_dump
Run: ./calendar_dump (accept Calendar and Reminders access)
Output: events.json in the current directory.
Includes today's events + incomplete reminders due by end of day.
| import EventKit | |
| let eventStore = EKEventStore() | |
| let now = Date() | |
| let startOfDay = Calendar.current.startOfDay(for: now) | |
| let endOfDay = Calendar.current.date(byAdding: .day, value: 1, to: startOfDay)! | |
| func iso(_ date: Date?) -> String? { | |
| guard let date = date else { return nil } | |
| let formatter = ISO8601DateFormatter() | |
| return formatter.string(from: date) | |
| } | |
| eventStore.requestFullAccessToEvents { granted, _ in | |
| guard granted else { | |
| print("Access denied to Calendar") | |
| exit(1) | |
| } | |
| var results: [[String: Any]] = [] | |
| // MARK: Calendar Events | |
| let calendars = eventStore.calendars(for: .event) | |
| let predicate = eventStore.predicateForEvents(withStart: startOfDay, end: endOfDay, calendars: calendars) | |
| let events = eventStore.events(matching: predicate).sorted { $0.startDate < $1.startDate } | |
| for event in events { | |
| let timezoneId = event.timeZone?.identifier ?? TimeZone.current.identifier | |
| results.append([ | |
| "type": "event", | |
| "calendar": event.calendar.title, | |
| "title": event.title ?? "Untitled", | |
| "start": iso(event.startDate) ?? "", | |
| "end": iso(event.endDate) ?? "", | |
| "timezone": timezoneId, | |
| "allDay": event.isAllDay, | |
| "highPriority": false | |
| ]) | |
| } | |
| // MARK: Reminders | |
| eventStore.requestFullAccessToReminders { granted, _ in | |
| guard granted else { | |
| print("Access denied to Reminders") | |
| exit(1) | |
| } | |
| // Include reminders due today and any past due (incomplete, due <= endOfDay) | |
| let predicate = eventStore.predicateForIncompleteReminders(withDueDateStarting: nil, ending: endOfDay, calendars: nil) | |
| eventStore.fetchReminders(matching: predicate) { reminders in | |
| reminders?.forEach { reminder in | |
| let isHigh = reminder.priority > 0 && reminder.priority <= 3 | |
| let dueDate = reminder.dueDateComponents?.date | |
| let isOverdue = { | |
| guard let d = dueDate else { return false } | |
| return d < now | |
| }() | |
| let dueToday = { | |
| guard let d = dueDate else { return false } | |
| return d >= startOfDay && d < endOfDay | |
| }() | |
| results.append([ | |
| "type": "reminder", | |
| "calendar": reminder.calendar.title, | |
| "title": reminder.title, | |
| "start": iso(reminder.startDateComponents?.date) ?? "", | |
| "due": iso(reminder.dueDateComponents?.date) ?? "", | |
| "priority": reminder.priority, | |
| "highPriority": isHigh, | |
| "overdue": isOverdue, | |
| "completed": reminder.isCompleted, | |
| "dueToday": dueToday | |
| ]) | |
| } | |
| // Write to events.json | |
| let fileURL = URL(fileURLWithPath: FileManager.default.currentDirectoryPath).appendingPathComponent("events.json") | |
| if let json = try? JSONSerialization.data(withJSONObject: results, options: .prettyPrinted) { | |
| do { | |
| try json.write(to: fileURL) | |
| print("✅ events.json written to \(fileURL.path)") | |
| } catch { | |
| print("❌ Failed to write file: \(error)") | |
| } | |
| } else { | |
| print("❌ Failed to serialize JSON") | |
| } | |
| exit(0) | |
| } | |
| } | |
| } | |
| RunLoop.current.run() |