feat: Apple Reminders two-way sync with calendarItemIdentifier storage#6161
feat: Apple Reminders two-way sync with calendarItemIdentifier storage#6161
Conversation
Add apple_reminder_id to UpdateActionItemRequest and ActionItemResponse models for storing EventKit calendarItemIdentifier. Add new GET /v1/action-items/pending-sync endpoint that returns items needing outbound sync (unexported) and inbound sync (have apple_reminder_id).
Add get_unexported_action_items() for finding items needing outbound sync and get_action_items_with_reminder_id() for finding items needing inbound completion sync.
- addReminder now returns calendarItemIdentifier instead of bool
- syncBatchFromJSON returns [{actionItemId, calendarItemIdentifier}]
- Fix calendar source to use defaultCalendarForNewReminders (iCloud)
- Remove UserDefaults 100-item dedup cap
- Add getRemindersStatus for batch identifier lookup
- Add updateReminder for updating by identifier
- Add deleteReminder for deleting by identifier
Update handleAppleRemindersSync to send calendarItemIdentifier mappings instead of plain action item IDs via markExportedBatch.
Store the EventKit calendarItemIdentifier on the action item model for two-way Apple Reminders sync.
Add appleReminderId parameter to updateActionItem for storing the EventKit identifier. Add getPendingSyncItems() for fetching items that need outbound or inbound Apple Reminders sync.
- addReminder returns calendarItemIdentifier string instead of bool - Update FCM/background sync handlers for new mapping format - Add getRemindersStatus for batch identifier lookup - Add updateReminderById and deleteReminderById methods
Update _handleAppleRemindersExport to capture and store the calendarItemIdentifier when manually exporting to Apple Reminders.
New orchestrator that runs on foreground resume with 30s debounce: - Outbound: creates reminders for unexported items, stores identifiers - Inbound: detects completion changes in Apple Reminders, syncs back
Add lifecycle hook in HomePage to run AppleRemindersSyncService on app resume, then refresh action items UI after sync completes.
Expand getRemindersStatus to return notes and dueDate fields from EventKit reminders, enabling full bidirectional field sync.
Filter pending_export by the integration's created_at timestamp so enabling Apple Reminders doesn't dump all existing action items. Also add due_at to synced_items response for bidirectional due date sync.
Check TaskIntegrationProvider.selectedApp before triggering sync on foreground resume to avoid unnecessary network and EventKit calls.
Sync title, due date, and completion in both directions: - Omi changed since last sync → push all fields to reminder - Otherwise → pull all reminder fields to Omi - Completion is always merged (if either side completed, both complete)
|
Merge this please |
|
Closing in favor of a clean reimplementation. The accumulated fixes made this PR hard to review. |
|
Hey @mdmohsin7 👋 Thank you so much for taking the time to contribute to Omi! We truly appreciate you putting in the effort to submit this pull request. After careful review, we've decided not to merge this particular PR. Please don't take this personally — we genuinely try to merge as many contributions as possible, but sometimes we have to make tough calls based on:
Your contribution is still valuable to us, and we'd love to see you contribute again in the future! If you'd like feedback on how to improve this PR or want to discuss alternative approaches, please don't hesitate to reach out. Thank you for being part of the Omi community! 💜 |
Summary
calendarItemIdentifier— Every Apple Reminder we create now returns its stable EventKit UUID, which is stored on the backend alongside the action item. This enables lookup, update, delete, and completion detection.AppleRemindersSyncServiceruns on every app foreground (30s debounce). Fetches unexported items from backend, creates reminders locally, stores identifiers back. No longer solely dependent on FCM silent push (which iOS throttles to ~2-3/hour).addRemindernow usesdefaultCalendarForNewReminders()instead of preferring.localsource, so reminders sync across devices via iCloud.UserDefaultsdedup mechanism replaced by backend identifier mapping.Changes
Backend (2 files)
apple_reminder_idfield onUpdateActionItemRequestandActionItemResponseGET /v1/action-items/pending-sync?platform=apple_remindersendpointiOS Native (2 files)
addReminderreturnscalendarItemIdentifierstring instead oftrue/falsesyncBatchFromJSONreturns[{actionItemId, calendarItemIdentifier}]mappingsgetRemindersStatus,updateReminder,deleteReminderDart (6 files modified, 1 new)
appleReminderIdfield onActionItemWithMetadataAppleRemindersServicewith new return types and methodsAppleRemindersSyncServiceorchestrator (outbound + inbound sync)AppLifecycleState.resumedinHomePageTest plan
🤖 Generated with Claude Code