# iOS Implementation Directive: App Launch Recovery & Missed Notification Detection

**Author**: Matthew Raymer  
**Date**: 2025-12-08  
**Status**: Active Implementation Directive - iOS Only  
**Version**: 1.0.0  
**Last Synced With Plugin Version**: v1.1.0

## Purpose

This directive provides **descriptive overview and integration guidance** for iOS-specific recovery and missed notification detection:

1. App Launch Recovery (cold/warm/terminated)
2. Missed Notification Detection
3. App Termination Detection
4. Background Task Registration for Boot Recovery

**⚠️ CRITICAL**: This document is **descriptive and integrative**. The **normative implementation instructions** are in the Phase 1–3 directives below. **If any code or behavior in this file conflicts with a Phase directive, the Phase directive wins.**

**Reference**: See [Plugin Requirements](./alarms/03-plugin-requirements.md) for requirements that Phase directives implement.

**Reference**: See [Platform Capability Reference](./alarms/01-platform-capability-reference.md) for iOS OS-level facts.

**⚠️ IMPORTANT**: For implementation, use the phase-specific directives (these are the canonical source of truth):

- **[Phase 1: Cold Start Recovery](./ios-implementation-directive-phase1.md)** - Minimal viable recovery
  - Implements: [Plugin Requirements §3.1.2](./alarms/03-plugin-requirements.md#312-app-cold-start) (iOS equivalent)
  - Explicit acceptance criteria, rollback safety, data integrity checks
  - **Start here** for fastest implementation
  
- **[Phase 2: App Termination Detection & Recovery](./ios-implementation-directive-phase2.md)** - Comprehensive termination handling
  - Implements: iOS-specific app termination scenarios
  - Prerequisite: Phase 1 complete
  
- **[Phase 3: Background Task Registration & Boot Recovery](./ios-implementation-directive-phase3.md)** - Background task enhancement
  - Implements: BGTaskScheduler registration for boot recovery
  - Prerequisites: Phase 1 and Phase 2 complete

**See Also**: [Unified Alarm Directive](./alarms/000-UNIFIED-ALARM-DIRECTIVE.md) for master coordination document.

---

## 1. Implementation Overview

### 1.1 What Needs to Be Implemented

| Feature | Status | Priority | Location |
| ------- | ------ | -------- | -------- |
| App Launch Recovery | ❌ Missing | **High** | `DailyNotificationPlugin.swift` - `load()` method |
| Missed Notification Detection | ⚠️ Partial | **High** | `DailyNotificationPlugin.swift` - new method |
| App Termination Detection | ❌ Missing | **High** | `DailyNotificationPlugin.swift` - recovery logic |
| Background Task Registration | ⚠️ Partial | **Medium** | `AppDelegate.swift` - BGTaskScheduler registration |

### 1.2 Implementation Strategy

**Phase 1** – Cold start recovery only
- Missed notification detection + future notification verification
- No termination detection, no boot handling
- **See [Phase 1 directive](./ios-implementation-directive-phase1.md) for implementation**

**Phase 2** – App termination detection & full recovery
- Termination detection via UNUserNotificationCenter state comparison
- Comprehensive recovery of all schedules (notify + fetch)
- Past notifications marked as missed, future notifications rescheduled
- **See [Phase 2 directive](./ios-implementation-directive-phase2.md) for implementation**

**Phase 3** – Background task registration & boot recovery
- BGTaskScheduler registration for boot recovery
- Next occurrence rescheduled for repeating schedules
- **See [Phase 3 directive](./ios-implementation-directive-phase3.md) for implementation**

---

## 2. iOS-Specific Considerations

### 2.1 Key Differences from Android

**iOS Advantages**:
- ✅ Notifications persist across app termination (OS-guaranteed)
- ✅ Notifications persist across device reboot (OS-guaranteed)
- ✅ No force stop equivalent (iOS doesn't have user-facing force stop)

**iOS Challenges**:
- ❌ App code does NOT run when notification fires (only if user taps)
- ❌ Background execution severely limited (BGTaskScheduler only)
- ❌ Cannot rely on background execution for recovery
- ❌ Must detect missed notifications on app launch

**Platform Reference**: See [Platform Capability Reference §3](./alarms/01-platform-capability-reference.md#3-ios-notification-capability-matrix) for complete iOS behavior matrix.

### 2.2 Recovery Scenario Mapping

**Android → iOS Mapping**:

| Android Scenario | iOS Equivalent | Detection Method |
| ---------------- | -------------- | --------------- |
| `COLD_START` | App Launch After Termination | Check if notifications exist vs DB state |
| `FORCE_STOP` | App Terminated by System | Check if notifications missing vs DB state |
| `BOOT` | Device Reboot | BGTaskScheduler registration (Phase 3) |
| `WARM_START` | App Resume (Foreground) | Check app state on resume |

**Note**: iOS doesn't have a user-facing "force stop" equivalent. System termination is detected by comparing UNUserNotificationCenter state with database state.

### 2.3 iOS APIs Used

**Notification Management**:
- `UNUserNotificationCenter.current()` - Notification center
- `UNUserNotificationCenter.getPendingNotificationRequests()` - Check scheduled notifications
- `UNUserNotificationCenter.add()` - Schedule notifications

**Background Tasks**:
- `BGTaskScheduler.shared` - Background task scheduler
- `BGTaskScheduler.register()` - Register background task handlers
- `BGAppRefreshTaskRequest` - Background fetch requests

**App Lifecycle**:
- `applicationWillTerminate` - App termination notification
- `applicationDidBecomeActive` - App foreground notification
- `applicationDidEnterBackground` - App background notification

---

## 3. Implementation: ReactivationManager (iOS)

**⚠️ Illustrative only** – See Phase 1 and Phase 2 directives for canonical implementation.

**ReactivationManager Responsibilities by Phase**:

| Phase | Responsibilities |
| ----- | ---------------- |
| 1 | Cold start only (missed detection + verify/reschedule future) |
| 2 | Adds termination detection & recovery |
| 3 | Background task registration & boot recovery |

**For implementation details, see**:
- [Phase 1: ReactivationManager creation](./ios-implementation-directive-phase1.md#2-implementation-reactivationmanager)
- [Phase 2: Termination detection](./ios-implementation-directive-phase2.md#2-implementation-termination-detection)

### 3.1 Create New File

**File**: `ios/Plugin/DailyNotificationReactivationManager.swift`

**Purpose**: Centralized recovery logic for app launch scenarios

### 3.2 Class Structure

**⚠️ Illustrative only** – See Phase 1 for canonical implementation.

```swift
import Foundation
import UserNotifications

/**
 * Manages recovery of notifications on app launch
 * Handles cold start, warm start, and termination recovery scenarios
 * 
 * @author Matthew Raymer
 * @version 1.0.0
 */
class DailyNotificationReactivationManager {
    
    private static let TAG = "DNP-REACTIVATION"
    private let notificationCenter = UNUserNotificationCenter.current()
    private let database: DailyNotificationDatabase
    private let storage: DailyNotificationStorage
    
    init(database: DailyNotificationDatabase, storage: DailyNotificationStorage) {
        self.database = database
        self.storage = storage
    }
    
    /**
     * Perform recovery on app launch
     * Detects scenario (cold/warm/termination) and handles accordingly
     */
    func performRecovery() async {
        do {
            NSLog("\(Self.TAG): Starting app launch recovery")
            
            // Step 1: Detect scenario
            let scenario = try await detectScenario()
            NSLog("\(Self.TAG): Detected scenario: \(scenario)")
            
            // Step 2: Handle based on scenario
            switch scenario {
            case .termination:
                try await handleTerminationRecovery()
            case .coldStart:
                try await handleColdStartRecovery()
            case .warmStart:
                try await handleWarmStartRecovery()
            case .none:
                NSLog("\(Self.TAG): No recovery needed")
            }
            
            NSLog("\(Self.TAG): App launch recovery completed")
        } catch {
            NSLog("\(Self.TAG): Error during app launch recovery: \(error)")
        }
    }
    
    // ... implementation methods below ...
}
```

---

## 4. Recovery Scenario Detection

### 4.1 Scenario Detection Algorithm

**Platform Reference**: [iOS §3.1.1](./alarms/01-platform-capability-reference.md#311-notifications-survive-app-termination) - Notifications survive app termination

**Detection Logic**:

```swift
enum RecoveryScenario {
    case none          // No recovery needed (first launch or warm resume)
    case coldStart     // App launched after termination, notifications may exist
    case termination   // App terminated, notifications missing vs DB
    case warmStart     // App resumed from background (optimization only)
}

func detectScenario() async throws -> RecoveryScenario {
    // Step 1: Check if database has schedules
    let schedules = try database.getEnabledSchedules()
    if schedules.isEmpty {
        return .none  // First launch
    }
    
    // Step 2: Get pending notifications from UNUserNotificationCenter
    let pendingNotifications = try await notificationCenter.pendingNotificationRequests()
    
    // Step 3: Compare DB state with notification center state
    let dbNotificationIds = Set(schedules.flatMap { $0.getScheduledNotificationIds() })
    let pendingIds = Set(pendingNotifications.map { $0.identifier })
    
    // Step 4: Determine scenario
    if pendingIds.isEmpty && !dbNotificationIds.isEmpty {
        // DB has schedules but no notifications scheduled
        return .termination
    } else if !pendingIds.isEmpty && !dbNotificationIds.isEmpty {
        // Both have data - check if they match
        if dbNotificationIds != pendingIds {
            return .coldStart  // Mismatch indicates recovery needed
        } else {
            return .warmStart  // Match indicates warm resume
        }
    }
    
    return .none
}
```

**For complete implementation, see**: [Phase 1 directive](./ios-implementation-directive-phase1.md#3-scenario-detection)

---

## 5. Missed Notification Detection

### 5.1 Detection Logic

**Platform Reference**: [iOS §3.2.1](./alarms/01-platform-capability-reference.md#321-app-code-does-not-run-when-notification-fires) - App code does not run when notification fires

**iOS Behavior**: When a notification fires, the app code does NOT execute. The notification is displayed, but the app must detect missed notifications on the next app launch.

**Detection Steps**:

1. Query database for notifications with `scheduled_time < currentTime`
2. Filter for notifications with `delivery_status != 'delivered'`
3. Mark as `'missed'` in database
4. Record in history table

**For complete implementation, see**: [Phase 1 directive](./ios-implementation-directive-phase1.md#4-missed-notification-detection)

---

## 6. Background Task Registration

### 6.1 BGTaskScheduler Registration

**Platform Reference**: [iOS §3.1.3](./alarms/01-platform-capability-reference.md#313-background-tasks-for-prefetching) - Background tasks for prefetching

**iOS Limitation**: BGTaskScheduler cannot be used for critical scheduling. It's system-controlled and not guaranteed.

**Use Case**: BGTaskScheduler is used for:
- Prefetching content (not critical timing)
- Boot recovery (system may defer)
- Background maintenance (best effort)

**Registration Location**: `AppDelegate.swift` or `SceneDelegate.swift`

**For complete implementation, see**: [Phase 3 directive](./ios-implementation-directive-phase3.md#2-background-task-registration)

---

## 7. Testing Strategy

### 7.1 iOS Testing Tools

**Simulator Testing**:
- `xcrun simctl` - Simulator control
- Xcode Instruments - Performance profiling
- Console.app - System log viewing

**Device Testing**:
- Xcode Device Console - Real device logs
- Settings → Developer → Background App Refresh - Control background execution

### 7.2 Test Scenarios

**Phase 1 Tests**:
- Cold start recovery
- Missed notification detection
- Future notification verification

**Phase 2 Tests**:
- App termination detection
- Comprehensive recovery
- Multiple schedules recovery

**Phase 3 Tests**:
- Background task registration
- Boot recovery (simulated)
- Background task execution

**For complete test procedures, see**: [iOS Test Scripts](../test-apps/ios-test-app/test-phase1.sh)

---

## 8. Platform-Specific Notes

### 8.1 Notification Persistence

**iOS Advantage**: Notifications persist automatically across:
- App termination
- Device reboot (for calendar/time triggers)

**App Responsibility**: Must still:
- Detect missed notifications on app launch
- Reschedule future notifications if needed
- Track delivery status in database

### 8.2 Background Execution Limits

**iOS Limitation**: Background execution is severely limited:
- BGTaskScheduler is system-controlled
- Cannot rely on background execution for recovery
- Must handle recovery on app launch

**Workaround**: Use BGTaskScheduler for prefetching only, not for critical scheduling.

### 8.3 Timing Tolerance

**iOS Limitation**: Calendar-based notifications have ±180 second tolerance.

**Impact**: Notifications may fire up to 3 minutes early or late.

**Mitigation**: Account for tolerance in missed notification detection logic.

---

## 9. Next Steps

1. **Start with Phase 1**: Implement cold start recovery
   - See [Phase 1 directive](./ios-implementation-directive-phase1.md)
   - Focus on missed notification detection
   - Verify future notifications are scheduled

2. **Proceed to Phase 2**: Add termination detection
   - See [Phase 2 directive](./ios-implementation-directive-phase2.md)
   - Implement comprehensive recovery
   - Handle multiple schedules

3. **Complete Phase 3**: Background task registration
   - See [Phase 3 directive](./ios-implementation-directive-phase3.md)
   - Register BGTaskScheduler handlers
   - Implement boot recovery

---

## 10. References

- [Platform Capability Reference](./alarms/01-platform-capability-reference.md) - iOS OS-level facts
- [Plugin Requirements](./alarms/03-plugin-requirements.md) - Requirements this directive implements
- [Android Implementation Directive](./android-implementation-directive.md) - Android equivalent for comparison
- [iOS Recovery Scenario Mapping](./ios-recovery-scenario-mapping.md) - Detailed scenario mapping
- [iOS Core Data Migration Guide](./ios-core-data-migration.md) - Database migration guide

---

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

