Files
daily-notification-plugin/docs/IOS_IMPLEMENTATION_CHECKLIST.md
Matthew a90d08c425 feat(ios): add Core Data DAO layer and unit tests
Implement comprehensive data access layer for Core Data entities:

- Add NotificationContentDAO, NotificationDeliveryDAO, and NotificationConfigDAO
  with full CRUD operations and query helpers
- Add DailyNotificationDataConversions utility for type conversions
  (Date ↔ Int64, Int ↔ Int32, JSON, optional strings)
- Update PersistenceController with entity verification and migration policies
- Add comprehensive unit tests for all DAO classes and data conversions
- Update Core Data model with NotificationContent, NotificationDelivery,
  and NotificationConfig entities (relationships and indexes)
- Integrate ReactivationManager into DailyNotificationPlugin.load()

DAO Features:
- Create/Insert methods with dictionary support
- Read/Query methods with predicates (by timesafariDid, notificationType,
  scheduledTime range, deliveryStatus, etc.)
- Update methods (touch, updateDeliveryStatus, recordUserInteraction)
- Delete methods (by ID, by key, delete all)
- Relationship management (NotificationContent ↔ NotificationDelivery)
- Cascade delete support

Test Coverage:
- 328 lines: DailyNotificationDataConversionsTests (time, numeric, string, JSON)
- 490 lines: NotificationContentDAOTests (CRUD, queries, updates)
- 415 lines: NotificationDeliveryDAOTests (CRUD, relationships, cascade delete)
- 412 lines: NotificationConfigDAOTests (CRUD, queries, active filtering)

All tests use in-memory Core Data stack for isolation and speed.

Completes sections 4.4, 4.5, and 6.0 of iOS implementation checklist.
2025-12-09 02:23:05 -08:00

17 KiB

iOS Implementation Checklist

Author: Matthew Raymer
Date: 2025-12-08
Status: 🎯 ACTIVE - Implementation Tracking
Version: 1.0.0

Purpose

Complete checklist of iOS code that needs to be implemented for feature parity with Android. This checklist tracks all implementation tasks with checkboxes.

Reference:


Phase 1: Cold Start Recovery (High Priority)

1.1 Create ReactivationManager

  • Create new file: ios/Plugin/DailyNotificationReactivationManager.swift
  • Implement class structure with properties:
    • notificationCenter: UNUserNotificationCenter
    • database: DailyNotificationDatabase
    • storage: DailyNotificationStorage
    • scheduler: DailyNotificationScheduler
    • TAG: String = "DNP-REACTIVATION"
  • Implement init(database:storage:scheduler:) initializer
  • Implement performRecovery() async method
  • Add timeout protection (2 seconds max)
  • Add error handling (non-fatal, log only)

1.2 Scenario Detection

  • Create RecoveryScenario enum:
    • .none - No recovery needed
    • .coldStart - App launched after termination
    • .termination - App terminated, notifications missing
    • .warmStart - App resumed (optimization)
  • Implement detectScenario() async throws -> RecoveryScenario:
    • Check if database has notifications (empty → .none)
    • Get pending notifications from UNUserNotificationCenter
    • Compare DB state with notification center state
    • Return appropriate scenario

1.3 Cold Start Recovery Logic

  • Implement performColdStartRecovery() async throws -> RecoveryResult:
    • Detect missed notifications (scheduled_time < now, not delivered)
    • Mark missed notifications in database (Phase 1: basic marking, Phase 2: add delivery_status)
    • Update last_delivery_attempt timestamp (Phase 2: add property)
    • Record in history table (Phase 1: logging only, Phase 2: database recording)
    • Verify future notifications are scheduled
    • Reschedule missing future notifications
    • Return RecoveryResult with counts

1.4 Missed Notification Detection

  • Implement detectMissedNotifications() async throws -> [NotificationContent]:
    • Query storage for notifications with scheduled_time < currentTime
    • Filter for missed notifications (Phase 1: time-based only, Phase 2: add delivery_status check)
    • Return list of missed notifications
  • Implement markMissedNotification(_:) async throws:
    • Mark notification as missed (Phase 1: basic, Phase 2: add delivery_status property)
    • Update notification in storage
    • Record status change (Phase 1: logging, Phase 2: history table)

1.5 Future Notification Verification

  • Implement verifyFutureNotifications() async throws -> VerificationResult:
    • Get all future notifications from storage
    • Get pending notifications from UNUserNotificationCenter
    • Compare notification IDs
    • Identify missing notifications
    • Return verification result
  • Implement rescheduleMissingNotification(id:) async throws:
    • For each missing notification, reschedule using DailyNotificationScheduler
    • Verify no duplicates created (scheduler handles this)
    • Log rescheduling activity

1.6 Recovery Result Types

  • Create RecoveryResult struct:
    • missedCount: Int
    • rescheduledCount: Int
    • verifiedCount: Int
    • errors: Int
  • Create VerificationResult struct:
    • totalSchedules: Int
    • notificationsFound: Int
    • notificationsMissing: Int
    • missingIds: [String]

1.7 Integration with Plugin

  • Add reactivationManager property to DailyNotificationPlugin
  • Initialize ReactivationManager in load() method
  • Call performRecovery() in load() method (async, non-blocking)
  • Add logging with DNP-REACTIVATION tag
  • Ensure recovery doesn't block app startup (Task-based async execution)

1.8 History Recording

  • Implement recordRecoveryHistory(_:scenario:) method:
    • Record recovery execution (Phase 1: logging with JSON, Phase 2: database table)
    • Include scenario, counts, outcome
    • Add diagnostic JSON with details
  • Implement recordRecoveryFailure(_:) method:
    • Record recovery errors (Phase 1: logging, Phase 2: database table)
    • Include error message and error type

1.9 Testing

  • Unit tests for scenario detection
  • Unit tests for missed notification detection
  • Unit tests for future notification verification
  • Unit tests for boot detection
  • Unit tests for recovery result types
  • Integration test for full recovery flow
  • Manual test with test scripts (test-phase1.sh)

Phase 2: App Termination Detection (High Priority)

2.1 Termination Detection Logic

  • Enhance detectScenario() to detect termination:
    • Check if DB has notifications but no pending notifications
    • Return .termination scenario
  • Implement handleTerminationRecovery() async throws:
    • Detect all missed notifications
    • Mark all as missed
    • Reschedule all future notifications
    • Reschedule all fetch schedules (if applicable)

2.2 Comprehensive Recovery

  • Implement performFullRecovery() async throws -> RecoveryResult:
    • Handle all notifications (missed and future)
    • Reschedule all missing notifications
    • Batch operations for efficiency
    • Return comprehensive result

2.3 Multiple Schedules Recovery

  • Implement recovery for multiple schedules:
    • Handle multiple notifications (batch processing)
    • Batch operations for efficiency (single pending request query)
    • Handle partial failures gracefully (continue on error)
    • Separate missed vs future notifications for batch processing

2.4 Testing

  • Test termination detection accuracy
  • Test full recovery with multiple schedules
  • Test partial failure scenarios
  • Manual test with test scripts (test-phase2.sh)

Phase 3: Background Task Registration & Boot Recovery (Medium Priority)

3.1 BGTaskScheduler Registration

  • Verify BGTaskScheduler registration in DailyNotificationPlugin.setupBackgroundTasks():
    • Check fetchTaskIdentifier registration (already implemented)
    • Check notifyTaskIdentifier registration (already implemented)
    • Add verification method verifyBGTaskRegistration() in ReactivationManager
  • Implement boot detection:
    • Check system uptime on app launch
    • Compare with last launch time (stored in UserDefaults)
    • Detect if boot occurred recently (< 60 seconds threshold)

3.2 Boot Recovery Logic

  • Implement performBootRecovery() async throws:
    • Detect all missed notifications (past scheduled times)
    • Mark all as missed
    • Reschedule all future notifications
    • Record boot recovery in history

3.3 Background Task Handlers

  • Enhance handleBackgroundFetch in DailyNotificationBackgroundTasks.swift:
    • Add recovery logic if needed
    • Schedule next background task
    • Handle expiration gracefully
  • Enhance handleBackgroundNotify:
    • Add recovery logic if needed
    • Schedule next background task

3.4 Testing

  • Test BGTaskScheduler registration
  • Test boot detection (simulate or manual)
  • Test boot recovery logic
  • Manual test with test scripts (test-phase3.sh)

Core Data Entities (High Priority)

4.1 NotificationContent Entity

  • Update DailyNotificationModel.xcdatamodeld:
    • Add NotificationContent entity
    • Add all 23 attributes (id, pluginVersion, timesafariDid, etc.)
    • Set correct attribute types (String, Date, Int32, Int64, Bool)
    • Add default values where specified
    • Mark required vs optional attributes
  • Add indexes:
    • timesafariDid index
    • notificationType index
    • scheduledTime index
  • Note: Core Data auto-generates class files with codeGenerationType="class"
  • Implement data conversion helpers (if needed):
    • DateLong (epoch milliseconds) conversion helpers
    • Int64Long conversion helpers

4.2 NotificationDelivery Entity

  • Update DailyNotificationModel.xcdatamodeld:
    • Add NotificationDelivery entity
    • Add all 20 attributes
    • Set correct attribute types
    • Add default values
  • Configure relationship:
    • Add notificationContent relationship (to-one)
    • Set deletion rule to Nullify (Core Data handles cascade via inverse)
    • Add inverse relationship deliveries (to-many) on NotificationContent
  • Add indexes:
    • notificationId index
    • deliveryTimestamp index
  • Note: Core Data auto-generates class files

4.3 NotificationConfig Entity

  • Update DailyNotificationModel.xcdatamodeld:
    • Add NotificationConfig entity
    • Add all 13 attributes
    • Set correct attribute types
    • Add default values
  • Add indexes:
    • configKey index
    • configType index
    • timesafariDid index
  • Note: Core Data auto-generates class files

4.4 Data Access Layer

  • Create DAO classes or extensions:
    • NotificationContentDAO or extension methods
    • NotificationDeliveryDAO or extension methods
    • NotificationConfigDAO or extension methods
  • Implement CRUD operations:
    • Create/Insert methods
    • Read/Query methods with predicates
    • Update methods
    • Delete methods
  • Implement query helpers:
    • Query by timesafariDid
    • Query by notificationType
    • Query by scheduledTime range
    • Query by deliveryStatus

4.5 Persistence Controller Updates

  • Update PersistenceController (if exists) or create:
    • Handle new entities in initialization
    • Add migration policies if needed
    • Test database initialization (unit tests verify Core Data stack)
  • Test Core Data stack:
    • Entity creation (tested in DAO unit tests)
    • Relationships (tested in NotificationDeliveryDAOTests)
    • Cascade delete (tested in NotificationDeliveryDAOTests)
    • Data conversion (tested in DailyNotificationDataConversionsTests)

API Methods (Medium Priority)

5.1 Notification Permission Methods

  • Implement getNotificationPermissionStatus():
    • Query UNUserNotificationCenter.current().getNotificationSettings()
    • Map to NotificationPermissionStatus type
    • Return authorization status
  • Implement requestNotificationPermission():
    • Request authorization via UNUserNotificationCenter
    • Handle user response
    • Return { granted: boolean }
  • Implement openNotificationSettings():
    • Open iOS Settings app to notification settings
    • Use UIApplication.shared.open() with settings URL

5.2 Background Task Methods

  • Implement getBackgroundTaskStatus():
    • Check BGTaskScheduler registration
    • Check Background App Refresh status (cannot check programmatically, return null)
    • Return BackgroundTaskStatus object
  • Implement openBackgroundAppRefreshSettings():
    • Open iOS Settings app to Background App Refresh
    • Use UIApplication.shared.open() with settings URL

5.3 Pending Notifications Method

  • Implement getPendingNotifications():
    • Query UNUserNotificationCenter.current().getPendingNotificationRequests()
    • Map to PendingNotification[] array
    • Return count and notification details
  • Add to pluginMethods array in DailyNotificationPlugin

5.4 Register Methods in Plugin

  • Add methods to pluginMethods array:
    • getNotificationPermissionStatus
    • requestNotificationPermission
    • getPendingNotifications
    • getBackgroundTaskStatus
    • openNotificationSettings
    • openBackgroundAppRefreshSettings

Data Type Conversions (High Priority)

6.1 Time Conversions

  • Create helper functions:
    • dateFromEpochMillis(_: Int64) -> Date
    • epochMillisFromDate(_: Date) -> Int64
  • Use in all Core Data operations:
    • When reading from database (Long → Date)
    • When writing to database (Date → Long)

6.2 Numeric Conversions

  • Ensure correct type mappings:
    • IntInt32 for small integers
    • LongInt64 for large integers
    • BooleanBool (direct)

6.3 String Conversions

  • Handle optional strings correctly:
    • String? in Swift maps to optional in Core Data
    • JSON fields stored as String?

Logging & Observability (Medium Priority)

7.1 Recovery Logging

  • Add comprehensive logging:
    • DNP-REACTIVATION: Starting app launch recovery
    • DNP-REACTIVATION: Detected scenario: [scenario]
    • DNP-REACTIVATION: Missed notifications detected: [count]
    • DNP-REACTIVATION: Future notifications verified: [count]
    • DNP-REACTIVATION: Recovery completed: [result]
  • Add error logging:
    • DNP-REACTIVATION: Recovery failed (non-fatal): [error]
    • Include error details and stack trace

7.2 Metrics Recording

  • Record recovery metrics in history table:
    • Recovery execution time
    • Missed notification count
    • Rescheduled notification count
    • Error count
  • Add diagnostic JSON to history entries

Error Handling (High Priority)

8.1 Recovery Error Handling

  • Ensure all recovery methods catch errors:
    • Database errors (non-fatal)
    • Notification center errors (non-fatal)
    • Scheduling errors (non-fatal)
  • Log errors but don't crash app
  • Return partial results if some operations fail

8.2 Error Types

  • Define iOS-specific error codes:
    • NOTIFICATION_PERMISSION_DENIED
    • BACKGROUND_REFRESH_DISABLED
    • PENDING_NOTIFICATION_LIMIT_EXCEEDED
    • BG_TASK_NOT_REGISTERED
    • BG_TASK_EXECUTION_FAILED
  • Map to error responses in plugin methods

Testing (High Priority)

9.1 Unit Tests

  • Test ReactivationManager initialization (DailyNotificationReactivationManagerTests)
  • Test scenario detection logic:
    • Test .none scenario (empty database)
    • Test .coldStart scenario
    • Test .termination scenario
    • Test .warmStart scenario
  • Test missed notification detection
  • Test future notification verification
  • Test recovery result creation
  • Test data conversions (DailyNotificationDataConversionsTests)
  • Test NotificationContentDAO (NotificationContentDAOTests)
  • Test NotificationDeliveryDAO (NotificationDeliveryDAOTests)
  • Test NotificationConfigDAO (NotificationConfigDAOTests)

9.2 Integration Tests

  • Test full recovery flow:
    • Schedule notification
    • Terminate app
    • Launch app
    • Verify recovery executed
    • Verify notifications rescheduled
  • Test error handling:
    • Test database errors
    • Test notification center errors
    • Verify app doesn't crash

9.3 Manual Testing

  • Run test-phase1.sh script
  • Run test-phase2.sh script
  • Run test-phase3.sh script
  • Test on physical device (not just simulator)
  • Test with Background App Refresh enabled/disabled
  • Test with notification permission granted/denied

Documentation Updates (Low Priority)

10.1 Code Documentation

  • Add file-level documentation to DailyNotificationReactivationManager.swift
  • Add method-level documentation to all public methods
  • Add parameter documentation
  • Add return value documentation
  • Add error documentation

10.2 Implementation Status

  • Update ios/Plugin/README.md with implementation status
  • Mark completed features as
  • Update version numbers
  • Update "Last Updated" dates

Summary

Total Tasks: ~150+ implementation tasks

Priority Breakdown:

  • High Priority: ~80 tasks (Phase 1, Core Data, API methods, Error handling)
  • Medium Priority: ~50 tasks (Phase 2, Phase 3, Logging)
  • Low Priority: ~20 tasks (Documentation)

Estimated Implementation Time:

  • Phase 1: 2-3 days
  • Phase 2: 1-2 days
  • Phase 3: 1 day
  • Core Data: 2-3 days
  • API Methods: 1 day
  • Testing: 2-3 days
  • Total: ~10-15 days

Document Version: 1.0.0
Last Updated: 2025-12-08
Next Review: After Phase 1 implementation