APPLE_INTEGRATION_COMPLETE.mdView source

Apple Integration - Complete Implementation

Overview

The OpenResponses app now has full integration with Apple Calendar and Reminders through the EventKit framework. This integration follows the MCP (Model Context Protocol) pattern and is fully integrated with the OpenAI API.

Architecture

Core Components

1. Service Layer (/OpenResponses/Core/Services/)

  • EventKitPermissionManager.swift - Centralized permission management for EventKit

    • iOS 17+ API support (requestFullAccessToEvents, requestFullAccessToReminders)
    • Fallback for iOS <17 (requestAccess)
    • Sendable, async/await patterns
  • AppleCalendarRepository.swift - Calendar data operations

    • fetchEvents() - Query calendar events by date range
    • createEvent() - Create new calendar events
    • ISO8601 date formatting built-in
  • AppleReminderRepository.swift - Reminders data operations

    • fetchReminders() - Query reminders with filters
    • createReminder() - Create new reminders with due dates

2. Provider Layer (/OpenResponses/Core/ToolProviders/)

  • AppleProvider.swift - MCP-compliant tool provider
    • Implements ToolProvider protocol
    • Four capabilities: listCalendarEvents, createCalendarEvent, listReminders, createReminder
    • Permission checking: hasCalendarAccess(), hasRemindersAccess()
    • Data models: AppleCalendarEventDetail, AppleReminderDetail

3. Data Models (/OpenResponses/Core/Models/)

  • AppleDataModels.swift
    • AppleCalendarItemSummary - Lightweight event representation
    • AppleReminderSummary - Lightweight reminder representation
    • AppleDataAccessError - Typed error handling

4. ViewModel Integration (/OpenResponses/Features/Chat/ViewModels/)

  • ChatViewModel.swift - Function call handlers
    • case "fetchAppleCalendarEvents" - List calendar events
    • case "createAppleCalendarEvent" - Create calendar event
    • case "fetchAppleReminders" - List reminders
    • case "createAppleReminder" - Create reminder
    • Streaming status updates for all Apple operations

5. OpenAI API Integration (/OpenResponses/Core/Services/)

  • OpenAIService.swift - Tool registration in buildTools()
    • Four functions registered with full APICapabilities.Function schemas
    • Conditional registration based on permission status
    • Proper JSONSchema definitions for all parameters

6. Settings UI (/OpenResponses/Features/Settings/)

  • SettingsHomeView.swift - Apple Integrations Card
    • Real-time permission status display
    • Connect buttons for Calendar and Reminders
    • Live status updates when permissions change

7. Dependency Injection (/OpenResponses/App/)

  • AppContainer.swift - Central service registration
    • EventKitPermissionManager.shared
    • AppleCalendarRepository
    • AppleReminderRepository
    • AppleProvider with all dependencies

API Functions Exposed to OpenAI

1. fetchAppleCalendarEvents

{
  "name": "fetchAppleCalendarEvents",
  "description": "List calendar events from Apple Calendar within a date range.",
  "parameters": {
    "startDate": "string (ISO 8601)",
    "endDate": "string (ISO 8601)",
    "calendarIdentifiers": "array of strings (optional)"
  }
}

2. createAppleCalendarEvent

{
  "name": "createAppleCalendarEvent",
  "description": "Create a new event in Apple Calendar.",
  "parameters": {
    "title": "string (required)",
    "startDate": "string (ISO 8601, required)",
    "endDate": "string (ISO 8601, required)",
    "location": "string (optional)",
    "notes": "string (optional)",
    "calendarIdentifier": "string (optional)"
  }
}

3. fetchAppleReminders

{
  "name": "fetchAppleReminders",
  "description": "List reminders from Apple Reminders app.",
  "parameters": {
    "completed": "boolean (optional)",
    "startDate": "string (ISO 8601, optional)",
    "endDate": "string (ISO 8601, optional)"
  }
}

4. createAppleReminder

{
  "name": "createAppleReminder",
  "description": "Create a new reminder in Apple Reminders app.",
  "parameters": {
    "title": "string (required)",
    "notes": "string (optional)",
    "dueDate": "string (ISO 8601, optional)",
    "priority": "integer (optional, 1=high, 5=medium, 9=low, 0=none)"
  }
}

Permission Handling

Info.plist Keys

  • NSCalendarsFullAccessUsageDescription - Required on iOS 17+ for reading calendar events.
  • NSRemindersFullAccessUsageDescription - Required on iOS 17+ for reading reminders.
  • NSCalendarsUsageDescription - Legacy fallback usage string for older EventKit authorization flows.
  • NSRemindersUsageDescription - Legacy fallback usage string for older EventKit authorization flows.

Permission Flow

  1. User navigates to Settings > Apple Integrations
  2. Taps “Connect” for Calendar or Reminders
  3. System permission dialog appears
  4. Upon grant, status updates to “Authorized” or “Full Access” (iOS 17+)
  5. Tools automatically become available to AI model

iOS Version Compatibility

  • iOS 17+: Uses requestFullAccessToEvents() and requestFullAccessToReminders()
  • iOS <17: Falls back to requestAccess(to:completion:)
  • Status checks use EKAuthorizationStatus enum (.authorized, .fullAccess, .denied, .restricted, .writeOnly)
  • Reminder reads should use EventKit’s reminder-specific predicates: predicateForIncompleteReminders(withDueDateStarting:ending:calendars:) and predicateForCompletedReminders(withCompletionDateStarting:ending:calendars:)
  • Local-day Apple queries should be evaluated in the device time zone. If an upstream tool emits UTC midnight/end-of-day timestamps for a local-day query, normalize those boundaries back to the device’s local day before running the EventKit fetch.

User Experience

Streaming Status Updates

When the AI calls Apple functions, the user sees:

  • 📅 “Fetching Apple Calendar events” → Calendar icon badge
  • 📅 “Creating calendar event” → Calendar icon badge
  • ✅ “Fetching Apple Reminders” → Reminders icon badge
  • 📝 “Creating Apple Reminder” → Reminders icon badge

Error Handling

All operations include comprehensive error handling:

  • Permission denied → Clear message with Settings guidance
  • Invalid date formats → Descriptive error with format example
  • Calendar not writable → Error message indicating read-only calendar
  • Framework unavailable → Platform compatibility message

Testing Checklist

Manual Testing

  • Settings UI shows correct initial permission status
  • Tapping “Connect” triggers system permission dialog
  • Permission status updates after grant/deny
  • Calendar events can be queried by date range
  • Calendar events can be created with all parameters
  • Reminders can be queried with filters
  • Reminders can be created with due dates
  • AI can invoke all four functions via chat
  • Streaming status shows during tool execution
  • Error messages are user-friendly

Edge Cases

  • iOS 17 vs iOS 16 permission APIs work correctly
  • Default calendar is used when identifier not specified
  • Multiple calendars can be filtered
  • All-day events are handled correctly
  • Timezone handling is correct for ISO8601 dates
  • Attendee names are extracted correctly

Documentation Updates

Files Modified/Created

  1. AppleProvider.swift - Created MCP provider
  2. EventKitPermissionManager.swift - Created permission manager
  3. AppleCalendarRepository.swift - Created calendar repo
  4. AppleReminderRepository.swift - Created reminder repo
  5. AppleDataModels.swift - Created data models & errors
  6. ToolProvider.swift - Added .apple ToolKind & 4 capabilities
  7. AppContainer.swift - Registered Apple services
  8. ChatViewModel.swift - Added 4 function handlers & streaming status
  9. OpenAIService.swift - Added 4 function definitions in buildTools()
  10. SettingsHomeView.swift - Added Apple Integrations Card
  11. project.pbxproj - Added current EventKit privacy usage descriptions for calendar/reminder full access

Documentation Created

  • /docs/APPLE_INTEGRATION_COMPLETE.md - This file

Next Steps

  1. Build and run on physical iOS device (Simulator has limited EventKit support)
  2. Test on iOS 17+ device to verify full access flow
  3. Test on iOS 16 device to verify fallback flow
  4. Have AI create calendar event via natural language
  5. Have AI query events and create reminders based on results

Potential Enhancements

  • Add calendar list/discovery function
  • Add reminder list/discovery function
  • Support event attendee management
  • Support event recurrence rules
  • Support reminder subtasks (iOS 16+)
  • Add calendar event deletion
  • Add reminder completion toggle

Security & Privacy

Data Handling

  • All EventKit data stays on-device
  • No calendar/reminder data sent to OpenAI API (only function parameters)
  • Permissions requested only when user initiates connection
  • User can revoke permissions via iOS Settings at any time

Best Practices

  • Minimal data exposure (only requested fields)
  • ISO8601 format ensures timezone clarity
  • Error messages don’t leak sensitive data
  • Logging respects user privacy

Conclusion

The Apple integration is implemented for the current product scope. All components follow the established architectural patterns, integrate directly with the OpenAI API, and provide a polished user experience. The implementation is unified, non-redundant, and ready for end-to-end testing.