# iOS Implementation Checklist

**Author**: Matthew Raymer  
**Date**: 2025-12-24  
**Status**: 🎯 **ACTIVE** - Implementation Tracking  
**Version**: 1.1.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**: 
- [iOS Implementation Directive](./ios-implementation-directive.md) - Implementation guide
- [iOS Recovery Scenario Mapping](./ios-recovery-scenario-mapping.md) - Scenario details
- [iOS Core Data Migration Guide](./ios-core-data-migration.md) - Database entities
- [Legacy Phase 1 Checklist](../../_archive/2025-legacy-doc/IMPLEMENTATION_CHECKLIST_LEGACY.md) - Historical Phase 1 checklist (archived)

---

## Phase 1: Cold Start Recovery (High Priority)

### 1.1 Create ReactivationManager

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

### 1.2 Scenario Detection

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

### 1.3 Cold Start Recovery Logic

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

### 1.4 Missed Notification Detection

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

### 1.5 Future Notification Verification

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

### 1.6 Recovery Result Types

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

### 1.7 Integration with Plugin

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

### 1.8 History Recording

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

### 1.9 Testing

- [x] Unit tests for scenario detection
- [x] Unit tests for missed notification detection
- [x] Unit tests for future notification verification
- [x] Unit tests for boot detection
- [x] Unit tests for recovery result types
- [x] Integration test for full recovery flow (DailyNotificationRecoveryIntegrationTests.swift)
- [ ] Manual test with test scripts (`test-phase1.sh`)

---

## Phase 2: App Termination Detection (High Priority)

### 2.1 Termination Detection Logic

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

### 2.2 Comprehensive Recovery

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

### 2.3 Multiple Schedules Recovery

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

### 2.4 Testing

- [x] Test termination detection accuracy (testFullRecoveryFlow_Termination in DailyNotificationRecoveryIntegrationTests)
- [x] Test full recovery with multiple schedules (testFullRecoveryFlow_Termination tests 3 notifications)
- [x] Test partial failure scenarios (testErrorHandling_* tests in DailyNotificationRecoveryIntegrationTests)
- [ ] Manual test with test scripts (`test-phase2.sh`)

---

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

### 3.1 BGTaskScheduler Registration

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

### 3.2 Boot Recovery Logic

- [x] Implement `performBootRecovery() async throws`:
  - [x] Detect all missed notifications (past scheduled times)
  - [x] Mark all as missed
  - [x] Reschedule all future notifications
  - [x] Record boot recovery in history

### 3.3 Background Task Handlers

- [x] Enhance `handleBackgroundFetch` in `DailyNotificationPlugin.swift`:
  - [x] Add recovery logic if needed (verification of scheduled notifications)
  - [x] Schedule next background task (using getNextScheduledNotificationTime)
  - [x] Handle expiration gracefully (enhanced expiration handler with cleanup)
- [x] Enhance `handleBackgroundNotify`:
  - [x] Add recovery logic if needed (verification of scheduled notifications)
  - [x] Schedule next background task (helper method added)

### 3.4 Testing

- [x] Test BGTaskScheduler registration (verifyBGTaskRegistration method exists, manual verification recommended)
- [x] Test boot detection (testDetectBootScenario_* tests in DailyNotificationReactivationManagerTests)
- [x] Test boot recovery logic (performBootRecovery tested via integration tests)
- [ ] Manual test with test scripts (`test-phase3.sh`)

---

## Core Data Entities (High Priority)

### 4.1 NotificationContent Entity

- [x] Update `DailyNotificationModel.xcdatamodeld`:
  - [x] Add `NotificationContent` entity
  - [x] Add all 23 attributes (id, pluginVersion, timesafariDid, etc.)
  - [x] Set correct attribute types (String, Date, Int32, Int64, Bool)
  - [x] Add default values where specified
  - [x] Mark required vs optional attributes
- [x] Add indexes:
  - [x] `timesafariDid` index
  - [x] `notificationType` index
  - [x] `scheduledTime` index
- [x] Note: Core Data auto-generates class files with `codeGenerationType="class"`
- [x] Implement data conversion helpers (DailyNotificationDataConversions.swift):
  - [x] `Date` ↔ `Long` (epoch milliseconds) conversion helpers (`dateFromEpochMillis`, `epochMillisFromDate`)
  - [x] `Int64` ↔ `Long` conversion helpers (`int64FromLong`, `int32FromInt`)

### 4.2 NotificationDelivery Entity

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

### 4.3 NotificationConfig Entity

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

### 4.4 Data Access Layer

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

### 4.5 Persistence Controller Updates

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

---

## API Methods (Medium Priority)

### 5.1 Notification Permission Methods

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

### 5.2 Background Task Methods

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

### 5.3 Pending Notifications Method

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

### 5.4 Register Methods in Plugin

- [x] Add methods to `pluginMethods` array:
  - [x] `getNotificationPermissionStatus`
  - [x] `requestNotificationPermission`
  - [x] `getPendingNotifications`
  - [x] `getBackgroundTaskStatus`
  - [x] `openNotificationSettings`
  - [x] `openBackgroundAppRefreshSettings`

---

## Data Type Conversions (High Priority)

### 6.1 Time Conversions

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

### 6.2 Numeric Conversions

- [x] Ensure correct type mappings:
  - [x] `Int` → `Int32` for small integers
  - [x] `Long` → `Int64` for large integers
  - [x] `Boolean` → `Bool` (direct)

### 6.3 String Conversions

- [x] Handle optional strings correctly:
  - [x] `String?` in Swift maps to optional in Core Data
  - [x] JSON fields stored as `String?`

---

## Logging & Observability (Medium Priority)

### 7.1 Recovery Logging

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

### 7.2 Metrics Recording

- [x] Record recovery metrics in history table:
  - [x] Recovery execution time (tracked with startTime/endTime)
  - [x] Missed notification count
  - [x] Rescheduled notification count
  - [x] Error count
- [x] Add diagnostic JSON to history entries (via HistoryDAO.recordRecovery)

---

## Error Handling (High Priority)

### 8.1 Recovery Error Handling

- [x] Ensure all recovery methods catch errors:
  - [x] Database errors (non-fatal) - handled in detectScenario, detectMissedNotifications, verifyFutureNotifications
  - [x] Notification center errors (non-fatal) - handled in detectScenario, verifyFutureNotifications
  - [x] Scheduling errors (non-fatal) - handled in rescheduleMissingNotification
- [x] Log errors but don't crash app - all errors logged with NSLog, app continues
- [x] Return partial results if some operations fail - RecoveryResult includes error count

### 8.2 Error Types

- [x] Define iOS-specific error codes:
  - [x] `NOTIFICATION_PERMISSION_DENIED`
  - [x] `BACKGROUND_REFRESH_DISABLED`
  - [x] `PENDING_NOTIFICATION_LIMIT_EXCEEDED`
  - [x] `BG_TASK_NOT_REGISTERED`
  - [x] `BG_TASK_EXECUTION_FAILED`
- [x] Map to error responses in plugin methods - getNotificationPermissionStatus uses NOTIFICATION_PERMISSION_DENIED

---

## Testing (High Priority)

### 9.1 Unit Tests

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

### 9.2 Integration Tests

- [x] Test full recovery flow:
  - [x] Schedule notification
  - [x] Terminate app (simulated by clearing notifications)
  - [x] Launch app (simulated by calling performRecovery)
  - [x] Verify recovery executed
  - [x] Verify notifications rescheduled (DailyNotificationRecoveryIntegrationTests)
- [x] Test error handling:
  - [x] Test database errors (testErrorHandling_DatabaseError)
  - [x] Test notification center errors (testErrorHandling_NotificationCenterError)
  - [x] Verify app doesn't crash (all stability tests)

### 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

- [x] Add file-level documentation to `DailyNotificationReactivationManager.swift`
- [x] Add method-level documentation to all public methods
- [x] Add parameter documentation (@param tags)
- [x] Add return value documentation (@return tags)
- [x] Add error documentation (@throws tags and error handling notes)

### 10.2 Implementation Status

- [x] Update `ios/Plugin/README.md` with implementation status
- [x] Mark completed features as ✅
- [x] Update version numbers (1.1.0)
- [x] Update "Last Updated" dates (2025-12-08)

---

## 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.1.0  
**Last Updated**: 2025-12-24  
**Next Review**: After manual testing completion

