44 KiB
iOS Android Parity Directive — iOS Implementation Upgrade
Status: 🎯 PLANNING - Directive for iOS-2 branch
Date: 2025-11-13
Author: Matthew Raymer
Branch: ios-2
Objective: Upgrade iOS implementation to match Android functionality while preserving Android code and TypeScript interface
Executive Summary
This directive outlines the plan to upgrade the iOS implementation of the Daily Notification Plugin to achieve feature parity with the functioning Android implementation. The Android codebase and TypeScript interface definitions will remain completely untouched during this work.
Key Constraints
- ✅ Android code must remain unchanged - No modifications to
src/android/directory - ✅ TypeScript interface must remain unchanged - No modifications to
src/definitions.ts - ✅ iOS implementation must match Android functionality - All Android
@PluginMethodmethods must have iOS equivalents - ✅ Platform-specific adaptations allowed - iOS can use Swift/iOS APIs but must provide same functionality
Testing & Scope
- ✅ Primary Testing Target: iOS Simulator
- ✅ Initial Scope: One scheduled prefetch + one scheduled notification per day
- Prefetch Timing: 5 minutes before notification time
- Notification Timing: User-specified daily time
- ✅ Test App:
ios-test-app(equivalent toandroid-test-app) with same HTML/JS UI - ✅ Rolling Window: Deferred to Phase 2 (initial implementation supports single daily schedule)
Readiness Milestones
- Phase 1: Test app ready for basic testing (one prefetch + one notification per day)
- Phase 3: Library ready for TimeSafari integration
- Phase 4: Full library ready for production TimeSafari integration
Current State Assessment
Android Implementation (Reference)
Location: src/android/DailyNotificationPlugin.java
Key Components:
- ✅
DailyNotificationPlugin.java- Main plugin class (1936 lines) - ✅
DailyNotificationStorage.java- Storage abstraction - ✅
DailyNotificationScheduler.java- AlarmManager-based scheduling - ✅
DailyNotificationFetcher.java- Background content fetching - ✅
DailyNotificationDatabase.java- SQLite database management - ✅
DailyNotificationRollingWindow.java- Rolling window safety - ✅
DailyNotificationExactAlarmManager.java- Exact alarm management - ✅
DailyNotificationRebootRecoveryManager.java- Reboot recovery - ✅
DailyNotificationTTLEnforcer.java- TTL enforcement - ✅
DailyNotificationETagManager.java- ETag caching - ✅
DailyNotificationJWTManager.java- JWT authentication - ✅
EnhancedDailyNotificationFetcher.java- TimeSafari API integration - ✅
DailyNotificationFetchWorker.java- WorkManager background worker - ✅
DailyNotificationReceiver.java- Broadcast receiver for alarms
Implemented Methods (from Android):
configure()- Plugin configuration with database/storage optionsscheduleDailyNotification()- Schedule daily notificationgetLastNotification()- Get last delivered notificationcancelAllNotifications()- Cancel all scheduled notificationsgetNotificationStatus()- Get current notification statusupdateSettings()- Update notification settingsgetBatteryStatus()- Get battery status informationrequestBatteryOptimizationExemption()- Request battery optimization exemptionsetAdaptiveScheduling()- Enable/disable adaptive schedulinggetPowerState()- Get current power statemaintainRollingWindow()- Manual rolling window maintenancegetRollingWindowStats()- Get rolling window statisticsgetExactAlarmStatus()- Get exact alarm statusrequestExactAlarmPermission()- Request exact alarm permissionopenExactAlarmSettings()- Open exact alarm settingsgetRebootRecoveryStatus()- Get reboot recovery statussetActiveDidFromHost()- Set activeDid from host (Phase 1)refreshAuthenticationForNewIdentity()- Refresh authentication (Phase 1)clearCacheForNewIdentity()- Clear cache for new identity (Phase 1)updateBackgroundTaskIdentity()- Update background task identity (Phase 1)testJWTGeneration()- Test JWT generation (Phase 1)testEndorserAPI()- Test Endorser.ch API (Phase 1)coordinateBackgroundTasks()- Coordinate background tasks (Phase 3)handleAppLifecycleEvent()- Handle app lifecycle events (Phase 3)getCoordinationStatus()- Get coordination status (Phase 3)scheduleDailyReminder()- Schedule static daily remindercancelDailyReminder()- Cancel daily remindergetScheduledReminders()- Get all scheduled remindersupdateDailyReminder()- Update existing daily reminder
iOS Implementation (Current)
Location: ios/Plugin/DailyNotificationPlugin.swift
Current Components:
- ✅
DailyNotificationPlugin.swift- Main plugin class (480 lines, partial) - ✅
DailyNotificationDatabase.swift- CoreData database (exists) - ✅
DailyNotificationRollingWindow.swift- Rolling window (exists) - ✅
DailyNotificationTTLEnforcer.swift- TTL enforcer (exists) - ✅
DailyNotificationETagManager.swift- ETag manager (exists) - ✅
DailyNotificationBackgroundTaskManager.swift- Background task manager (exists) - ✅
DailyNotificationConstants.swift- Constants (exists) - ✅
DailyNotificationErrorHandler.swift- Error handling (exists) - ✅
DailyNotificationLogger.swift- Logging (exists) - ✅
DailyNotificationPowerManager.swift- Power management (exists) - ✅
DailyNotificationPerformanceOptimizer.swift- Performance (exists) - ✅
DailyNotificationCallbacks.swift- Callbacks (exists) - ✅
DailyNotificationConfig.swift- Configuration (exists) - ✅
DailyNotificationModel.swift- Data models (exists) - ✅
DailyNotificationMaintenanceWorker.swift- Maintenance (exists)
Currently Implemented Methods:
- ✅
configure()- Basic configuration (needs enhancement) - ✅
scheduleContentFetch()- Basic BGTaskScheduler (needs enhancement) - ✅
scheduleUserNotification()- Basic UNUserNotificationCenter (needs enhancement) - ✅
scheduleDualNotification()- Dual scheduling (needs enhancement) - ✅
getDualScheduleStatus()- Status retrieval (needs enhancement) - ✅
scheduleDailyReminder()- Static reminders (implemented) - ✅
cancelDailyReminder()- Cancel reminders (implemented) - ✅
getScheduledReminders()- Get reminders (implemented) - ✅
updateDailyReminder()- Update reminders (implemented)
Missing Methods (Need Implementation):
- ❌
scheduleDailyNotification()- Main scheduling method - ❌
getLastNotification()- Last notification retrieval - ❌
cancelAllNotifications()- Cancel all notifications - ❌
getNotificationStatus()- Status retrieval - ❌
updateSettings()- Settings update - ❌
getBatteryStatus()- Battery status - ❌
requestBatteryOptimizationExemption()- Battery optimization - ❌
setAdaptiveScheduling()- Adaptive scheduling - ❌
getPowerState()- Power state - ❌
maintainRollingWindow()- Rolling window maintenance - ❌
getRollingWindowStats()- Rolling window stats - ❌
getExactAlarmStatus()- Exact alarm status (iOS equivalent) - ❌
requestExactAlarmPermission()- Alarm permission (iOS equivalent) - ❌
openExactAlarmSettings()- Alarm settings (iOS equivalent) - ❌
getRebootRecoveryStatus()- Reboot recovery status - ❌
setActiveDidFromHost()- ActiveDid management (Phase 1) - ❌
refreshAuthenticationForNewIdentity()- Auth refresh (Phase 1) - ❌
clearCacheForNewIdentity()- Cache clearing (Phase 1) - ❌
updateBackgroundTaskIdentity()- Background task identity (Phase 1) - ❌
testJWTGeneration()- JWT testing (Phase 1) - ❌
testEndorserAPI()- API testing (Phase 1) - ❌
coordinateBackgroundTasks()- Background coordination (Phase 3) - ❌
handleAppLifecycleEvent()- Lifecycle events (Phase 3) - ❌
getCoordinationStatus()- Coordination status (Phase 3)
Implementation Strategy
Testing Environment: iOS Simulator (primary testing target)
Initial Scope: Simplified daily schedule
- One scheduled prefetch per day (via BGTaskScheduler)
- Timing: 5 minutes before notification time
- One scheduled notification per day (via UNUserNotificationCenter)
- Timing: User-specified daily time
- Full rolling window and advanced features deferred to later phases
Phase 1: Core Infrastructure Parity
Objective: Implement core notification scheduling and management methods with simplified daily schedule
Tasks:
-
Storage Layer Enhancement
- Enhance
DailyNotificationStorage(Swift equivalent) to match AndroidDailyNotificationStorage.java - Support both UserDefaults and SQLite (CoreData) storage modes
- Implement content caching and retrieval
- Enhance
-
Scheduler Implementation
- Create
DailyNotificationScheduler.swiftequivalent toDailyNotificationScheduler.java - Use
UNUserNotificationCenterfor notification scheduling - Initial: Support single daily notification (one prefetch + one notification per day)
- Rolling window logic deferred to Phase 2
- Create
-
Background Fetching
- Enhance
DailyNotificationBackgroundTaskManager.swiftto match AndroidDailyNotificationFetcher.java - Implement
BGTaskSchedulerregistration and execution - Initial: Support single daily prefetch task (scheduled 5 minutes before notification)
- Add content fetching with ETag support
- Enhance
-
Core Methods Implementation
scheduleDailyNotification()- Main scheduling method (single daily schedule)getLastNotification()- Last notification retrievalcancelAllNotifications()- Cancel allgetNotificationStatus()- Status retrievalupdateSettings()- Settings update
Platform Adaptations:
- Android
AlarmManager→ iOSUNUserNotificationCenterwithUNCalendarNotificationTrigger - Android
WorkManager→ iOSBGTaskSchedulerwithBGAppRefreshTaskRequest - Android
SharedPreferences→ iOSUserDefaults(with SQLite option via CoreData)
Test App Readiness: Phase 1 test app should be ready for testing on iOS Simulator after core methods are implemented
Phase 2: Advanced Features Parity
Objective: Implement advanced features matching Android capabilities
Tasks:
-
Rolling Window Management
- Enhance
DailyNotificationRollingWindow.swiftto match Android implementation - Implement iOS-specific limits (64 pending notifications)
- Add maintenance scheduling
- Note: Expands beyond single daily schedule to support rolling window
- Enhance
-
TTL Enforcement
- Enhance
DailyNotificationTTLEnforcer.swiftto match Android implementation - Implement TTL checking at notification fire time
- Add stale content handling
- Enhance
-
Exact Alarm Equivalent
- Implement iOS equivalent of Android exact alarm management
- Use
UNTimeIntervalNotificationTriggerfor precise timing - Handle iOS notification delivery guarantees
-
Reboot Recovery
- Create
DailyNotificationRebootRecoveryManager.swiftequivalent - Use iOS app launch detection to reschedule notifications
- Implement recovery status tracking
- Create
-
Power Management
- Enhance
DailyNotificationPowerManager.swiftto match Android capabilities - Implement battery status checking
- Add background refresh status checking
- Enhance
Platform Adaptations:
- Android exact alarms → iOS notification delivery with time-based triggers
- Android battery optimization → iOS Background App Refresh settings
- Android reboot recovery → iOS app launch detection and rescheduling
Test App Readiness: Phase 2 test app should be ready for testing rolling window and advanced features on iOS Simulator
Phase 3: TimeSafari Integration Parity
Objective: Implement TimeSafari-specific integration features
Tasks:
-
JWT Management
- Create
DailyNotificationJWTManager.swiftequivalent - Implement JWT token generation and caching
- Add token refresh logic
- Create
-
ETag Management
- Enhance
DailyNotificationETagManager.swiftto match Android - Implement ETag caching and conditional requests
- Add ETag invalidation logic
- Enhance
-
Enhanced Fetcher
- Create
EnhancedDailyNotificationFetcher.swiftequivalent - Implement TimeSafari API integration
- Add activeDid support
- Create
-
Phase 1 Methods
setActiveDidFromHost()- ActiveDid managementrefreshAuthenticationForNewIdentity()- Auth refreshclearCacheForNewIdentity()- Cache clearingupdateBackgroundTaskIdentity()- Background task identitytestJWTGeneration()- JWT testingtestEndorserAPI()- API testing
Platform Adaptations:
- Android WorkManager background tasks → iOS BGTaskScheduler background tasks
- Android SharedPreferences for config → iOS UserDefaults for config
- Android JWT signing → iOS JWT signing (same algorithm, different implementation)
TimeSafari Integration Readiness: Library ready for TimeSafari integration after Phase 3 completion Test App Readiness: Phase 3 test app should be ready for testing TimeSafari integration features on iOS Simulator
Phase 4: Background Coordination Parity
Objective: Implement background task coordination features
Tasks:
-
Background Coordination
- Implement
coordinateBackgroundTasks()method - Add TimeSafari PlatformServiceMixin integration
- Coordinate BGTaskScheduler with app lifecycle
- Implement
-
Lifecycle Management
- Implement
handleAppLifecycleEvent()method - Handle app background/foreground events
- Sync state with app lifecycle
- Implement
-
Coordination Status
- Implement
getCoordinationStatus()method - Track coordination state
- Provide debugging information
- Implement
Platform Adaptations:
- Android app lifecycle callbacks → iOS app lifecycle notifications
- Android WorkManager coordination → iOS BGTaskScheduler coordination
TimeSafari Integration Readiness: Full library ready for production TimeSafari integration after Phase 4 completion Test App Readiness: Phase 4 test app should be ready for testing full background coordination on iOS Simulator
Component Mapping: Android → iOS
Core Components
| Android Component | iOS Equivalent | Status | Notes |
|---|---|---|---|
DailyNotificationPlugin.java |
DailyNotificationPlugin.swift |
✅ Partial | Needs method additions |
DailyNotificationStorage.java |
DailyNotificationStorage.swift |
❌ Missing | Create new file |
DailyNotificationScheduler.java |
DailyNotificationScheduler.swift |
❌ Missing | Create new file |
DailyNotificationFetcher.java |
DailyNotificationBackgroundTaskManager.swift |
✅ Exists | Needs enhancement |
DailyNotificationDatabase.java |
DailyNotificationDatabase.swift |
✅ Exists | CoreData-based |
DailyNotificationRollingWindow.java |
DailyNotificationRollingWindow.swift |
✅ Exists | Needs enhancement |
DailyNotificationExactAlarmManager.java |
iOS equivalent needed | ❌ Missing | Use UNUserNotificationCenter |
DailyNotificationRebootRecoveryManager.java |
iOS equivalent needed | ❌ Missing | Use app launch detection |
DailyNotificationTTLEnforcer.java |
DailyNotificationTTLEnforcer.swift |
✅ Exists | Needs enhancement |
DailyNotificationETagManager.java |
DailyNotificationETagManager.swift |
✅ Exists | Needs enhancement |
DailyNotificationJWTManager.java |
iOS equivalent needed | ❌ Missing | Create new file |
EnhancedDailyNotificationFetcher.java |
iOS equivalent needed | ❌ Missing | Create new file |
DailyNotificationFetchWorker.java |
BGTaskScheduler handler | ❌ Missing | Implement in plugin |
DailyNotificationReceiver.java |
Notification delegate | ❌ Missing | Implement in plugin |
Platform API Mapping
| Android API | iOS Equivalent | Implementation Notes |
|---|---|---|
AlarmManager.setExact() |
UNUserNotificationCenter.add() with UNCalendarNotificationTrigger |
Use calendar-based triggers for daily scheduling |
WorkManager.enqueue() |
BGTaskScheduler.submit() |
Use BGAppRefreshTaskRequest for background fetching |
SharedPreferences |
UserDefaults |
For simple key-value storage |
SQLiteDatabase |
CoreData / SQLite.swift |
For complex data storage |
NotificationManager |
UNUserNotificationCenter |
For notification delivery |
PowerManager |
UIDevice.batteryState |
For battery status |
BroadcastReceiver |
App lifecycle notifications | For reboot recovery |
PendingIntent |
UNNotificationRequest |
For scheduled notifications |
Method Implementation Checklist
Core Methods (Phase 1)
configure(options: ConfigureOptions)- Enhanced configurationscheduleDailyNotification(options: NotificationOptions)- Main schedulinggetLastNotification()- Last notification retrievalcancelAllNotifications()- Cancel all notificationsgetNotificationStatus()- Status retrievalupdateSettings(settings: NotificationSettings)- Settings updategetBatteryStatus()- Battery statusrequestBatteryOptimizationExemption()- Battery optimization (iOS: Background App Refresh)setAdaptiveScheduling(options: { enabled: boolean })- Adaptive schedulinggetPowerState()- Power state
Rolling Window Methods (Phase 2)
maintainRollingWindow()- Manual maintenancegetRollingWindowStats()- Statistics retrieval
Exact Alarm Methods (Phase 2) - iOS Equivalents
getExactAlarmStatus()- Notification delivery statusrequestExactAlarmPermission()- Notification permissionsopenExactAlarmSettings()- Open notification settings
Reboot Recovery Methods (Phase 2)
getRebootRecoveryStatus()- Recovery status
TimeSafari Integration Methods (Phase 3)
setActiveDidFromHost(options: { activeDid: string })- ActiveDid managementrefreshAuthenticationForNewIdentity(options: { activeDid: string })- Auth refreshclearCacheForNewIdentity()- Cache clearingupdateBackgroundTaskIdentity(options: { activeDid: string })- Background task identitytestJWTGeneration(options?: { activeDid?: string })- JWT testingtestEndorserAPI(options?: { activeDid?: string, apiServer?: string })- API testing
Background Coordination Methods (Phase 4)
coordinateBackgroundTasks()- Background coordinationhandleAppLifecycleEvent(options: { lifecycleEvent: string })- Lifecycle eventsgetCoordinationStatus()- Coordination status
Enhanced Dual Scheduling Methods (Already Partially Implemented)
scheduleContentFetch(config: ContentFetchConfig)- Needs enhancementscheduleUserNotification(config: UserNotificationConfig)- Needs enhancementscheduleDualNotification(config: DualScheduleConfiguration)- Needs enhancementgetDualScheduleStatus()- Needs enhancement
Reminder Methods (Already Implemented)
scheduleDailyReminder(options: ReminderOptions)- ✅ CompletecancelDailyReminder(options: { reminderId: string })- ✅ CompletegetScheduledReminders()- ✅ CompleteupdateDailyReminder(options: ReminderOptions)- ✅ Complete
Platform-Specific Considerations
Testing Environment
- Primary Testing Target: iOS Simulator
- Simulator Testing: All features should be testable on iOS Simulator
- Physical Device Testing: Optional for final validation
iOS Notification Limits
- Maximum Pending Notifications: 64 (system limit)
- Maximum Daily Notifications: ~20 (recommended)
- Initial Scope: One prefetch + one notification per day
- Rolling Window Strategy: Always arm today's notifications, arm tomorrow's if within limits (Phase 2+)
iOS Background Execution
- BGTaskScheduler Limits:
- Background refresh tasks: ~30 seconds execution time
- Processing tasks: Variable, depends on system resources
- Strategy: Efficient processing, immediate next-schedule after completion
iOS Storage Options
- UserDefaults: For simple configuration and preferences
- CoreData: For complex relational data (schedules, content cache)
- File System: For large content (images, media)
iOS Permission Model
- Notification Permissions: Required for all notification delivery
- Background App Refresh: Required for background fetching
- Strategy: Request permissions early, provide clear explanations
Testing Strategy
Unit Tests
- Test all new methods match Android behavior
- Test storage layer (UserDefaults and CoreData)
- Test scheduler with iOS notification limits
- Test background task execution
- Test TTL enforcement
- Test rolling window maintenance
Integration Tests
- Test full notification pipeline (fetch → cache → schedule → display)
- Test offline scenarios
- Test background execution reliability
- Test reboot recovery
- Test activeDid integration
Manual Testing
- Test on physical iOS devices
- Test Background App Refresh settings
- Test notification permissions
- Test battery optimization scenarios
- Test app lifecycle events
iOS Test App Requirements
UI Parity with Android
Objective: Create iOS test app with identical UI/UX to Android test app, using iOS plugin implementation
Reference App: test-apps/android-test-app/ (Standalone Android with HTML/JS UI)
Requirements:
-
Same UI as Android Test App
- Reuse exact HTML/JavaScript from
android-test-app/app/src/main/assets/public/index.html - Same button layout and functionality
- Same status display area
- Same visual design and styling
- Platform detection to use iOS plugin methods instead of Android
- Reuse exact HTML/JavaScript from
-
Platform Detection
- Detect iOS platform and use iOS plugin methods
- Show iOS-specific status indicators
- Display iOS-specific permission states
- Adapt Android-specific methods to iOS equivalents (e.g.,
openExactAlarmSettings→openNotificationSettings)
-
iOS Plugin Integration
- Use iOS
DailyNotificationPlugininstead of Android version - All method calls route to iOS native implementation
- Error handling adapted for iOS-specific errors
- Use iOS
File Structure:
test-apps/ios-test-app/
├── App/
│ ├── AppDelegate.swift # App delegate with plugin setup
│ ├── Info.plist # iOS permissions and config
│ ├── SceneDelegate.swift # Scene management (if needed)
│ └── Main.storyboard # Main storyboard (if needed)
├── App.xcodeproj/ # Xcode project
├── App.xcworkspace/ # Xcode workspace (if using CocoaPods)
├── Podfile # CocoaPods dependencies
└── www/ # Web assets (HTML/JS/CSS)
├── index.html # Same UI as android-test-app
├── capacitor.config.json # Capacitor config
└── capacitor.plugins.json # Plugin registration
iOS Permissions and Requirements
Required Permissions (Info.plist):
-
Notification Permissions
<key>UIBackgroundModes</key> <array> <string>remote-notification</string> <string>fetch</string> <string>processing</string> </array> -
Background Task Identifiers
<key>BGTaskSchedulerPermittedIdentifiers</key> <array> <string>com.timesafari.dailynotification.fetch</string> <string>com.timesafari.dailynotification.notify</string> </array> -
Usage Descriptions
<key>NSUserNotificationsUsageDescription</key> <string>TimeSafari needs notification permissions to deliver daily updates</string>
Runtime Permission Handling:
-
Notification Permissions
- Request via
UNUserNotificationCenter.requestAuthorization() - Check status via
UNUserNotificationCenter.getNotificationSettings() - Display permission status in test app UI
- Provide "Open Settings" button if denied
- Request via
-
Background App Refresh
- Check status via
UIApplication.shared.backgroundRefreshStatus - Display status in test app UI
- Provide guidance for enabling in Settings
- Check status via
-
Permission Status Display
- Show notification permission state (authorized/denied/not determined)
- Show background refresh state (available/restricted/denied)
- Show battery optimization status (iOS equivalent)
- Provide actionable buttons to request/enable permissions
iOS-Specific Requirements:
-
Background Task Registration
- Register BGTaskScheduler tasks in
AppDelegate.application(_:didFinishLaunchingWithOptions:) - Register handlers before app finishes launching
- Handle task expiration gracefully
- Register BGTaskScheduler tasks in
-
Notification Categories
- Define notification categories for actions
- Register categories with UNUserNotificationCenter
- Handle notification actions in delegate
-
App Lifecycle Integration
- Handle app background/foreground events
- Reschedule notifications on app launch
- Sync state on app resume
Build Options
Objective: Support both Xcode GUI and command-line builds with straightforward setup
Xcode Build (GUI)
Setup:
- Open
test-apps/ios-test-app/App.xcworkspace(if using CocoaPods) orApp.xcodeprojin Xcode - Select target device (simulator or physical device)
- Build and run via Xcode interface
Xcode Configuration:
- Scheme: ios-test-app (or similar)
- Configuration: Debug (development) / Release (production)
- Signing: Automatic signing with development team
- Capabilities:
- Push Notifications
- Background Modes (Remote notifications, Background fetch, Background processing)
Xcode Build Steps:
- Clean build folder (Cmd+Shift+K)
- Build project (Cmd+B)
- Run on device/simulator (Cmd+R)
- Attach debugger for debugging
Console Build (Command Line)
Objective: Enable straightforward command-line builds matching Android test app pattern
Build Script Pattern:
- Follow pattern from
scripts/build-native.sh - Create
scripts/build-ios-test-app.shfor iOS test app - Support both simulator and device builds
- Include dependency installation (CocoaPods)
- Include code signing configuration
Build Commands (via Script):
-
Build iOS Test App (Debug - Simulator)
./scripts/build-ios-test-app.sh --simulator -
Build iOS Test App (Debug - Device)
./scripts/build-ios-test-app.sh --device -
Build iOS Test App (Release)
./scripts/build-ios-test-app.sh --release
Direct xcodebuild Commands (if needed):
-
Install Dependencies
cd test-apps/ios-test-app pod install # If using CocoaPods -
Build iOS App (Debug - Simulator)
xcodebuild -workspace App.xcworkspace \ -scheme ios-test-app \ -configuration Debug \ -sdk iphonesimulator \ -destination 'platform=iOS Simulator,name=iPhone 15' \ build -
Build iOS App (Debug - Device)
xcodebuild -workspace App.xcworkspace \ -scheme ios-test-app \ -configuration Debug \ -sdk iphoneos \ -destination 'generic/platform=iOS' \ build -
Build iOS App (Release)
xcodebuild -workspace App.xcworkspace \ -scheme ios-test-app \ -configuration Release \ -sdk iphoneos \ -archivePath build/ios-test-app.xcarchive \ archive
Build Script Requirements:
- Check for required tools (xcodebuild, pod if using CocoaPods)
- Install dependencies automatically
- Support both simulator and device builds
- Provide clear error messages
- Follow same pattern as
scripts/build-native.sh(colors, logging, error handling)
Debugging Strategy
Objective: Make debugging easily accessible and comprehensive
Console Logging
Structured Logging:
-
Log Levels
DEBUG: Detailed diagnostic informationINFO: General informational messagesWARN: Warning messages for potential issuesERROR: Error messages for failures
-
Log Format
[DNP-PLUGIN] [LEVEL] [TIMESTAMP] [METHOD] MessageExample:
[DNP-PLUGIN] [INFO] [2025-11-13 10:30:45 UTC] [scheduleDailyNotification] Scheduling notification for 09:00 -
Log Categories
DNP-PLUGIN: Main plugin operationsDNP-SCHEDULER: Scheduling operationsDNP-FETCHER: Background fetchingDNP-STORAGE: Storage operationsDNP-TTL: TTL enforcementDNP-ROLLING-WINDOW: Rolling window maintenance
Logging Implementation:
- Use
os_logfor system-level logging (visible in Console.app) - Use
print()for Xcode console output - Include file/line information in debug builds
- Support log level filtering
Xcode Debugging
Breakpoints:
-
Strategic Breakpoints
- Plugin method entry points
- Background task handlers
- Notification scheduling logic
- Error handling paths
-
Conditional Breakpoints
- Break on specific notification IDs
- Break on error conditions
- Break on specific activeDid values
-
Logging Breakpoints
- Log method entry/exit without stopping
- Log variable values
- Log call stack
Debugging Tools:
-
LLDB Commands
- Inspect Swift objects
- Print variable values
- Execute Swift expressions
- View call stack
-
View Hierarchy Debugger
- Inspect UI components
- Debug layout issues
- Verify UI state
-
Network Debugging
- Monitor API calls
- Inspect request/response
- Debug authentication issues
Test App Debugging UI
Debug Panel in Test App:
-
Log Viewer
- Real-time log display
- Filter by log level
- Filter by category
- Search functionality
- Export logs to file
-
Status Dashboard
- Plugin initialization status
- Permission status
- Background task status
- Notification schedule status
- Storage status
-
Diagnostic Tools
- Test individual plugin methods
- View stored data (UserDefaults, CoreData)
- Trigger manual background tasks
- Force notification delivery
- Clear caches
-
Error Display
- Show recent errors
- Error details and stack traces
- Error reporting functionality
Debug View Implementation:
<!-- DebugView.vue -->
<template>
<div class="debug-view">
<h2>🔍 Debug Tools</h2>
<!-- Log Viewer -->
<LogViewer :logs="logs" />
<!-- Status Dashboard -->
<StatusDashboard :status="pluginStatus" />
<!-- Diagnostic Tools -->
<DiagnosticTools @test-method="testMethod" />
<!-- Error Display -->
<ErrorDisplay :errors="errors" />
</div>
</template>
Console.app Integration
System Logs:
- Use
os_logfor system-level logging - View logs in Console.app on macOS
- Filter by subsystem:
com.timesafari.dailynotification - Export logs for analysis
Log Export:
- Export logs from test app UI
- Export via Xcode Organizer
- Export via Console.app
- Include timestamps and log levels
Background Task Debugging
BGTaskScheduler Debugging:
-
Task Registration Verification
- Log task registration in AppDelegate
- Verify task identifiers match Info.plist
- Check task handler registration
-
Task Execution Monitoring
- Log task start/completion
- Log task expiration
- Monitor task execution time
- Track task success/failure
-
Task Scheduling Debugging
- Log scheduled task times
- Verify earliestBeginDate
- Check task submission success
- Monitor task cancellation
Debug Commands:
// In test app or debug build
func debugBackgroundTasks() {
// List registered tasks
// Show scheduled tasks
// Trigger test tasks
// View task history
}
Notification Debugging
Notification Delivery Debugging:
-
Scheduled Notifications
- List all pending notifications
- Show notification content
- Display trigger times
- Verify notification limits
-
Notification Delivery
- Log notification delivery
- Track delivery success/failure
- Monitor notification actions
- Debug notification display
-
Permission Debugging
- Check permission status
- Log permission requests
- Track permission changes
- Debug permission denials
Debug Methods:
// Debug notification state
func debugNotifications() {
// Get pending notifications
// Get delivered notifications
// Check notification settings
// Verify notification categories
}
Test App Implementation Checklist
- Create
ios-test-appdirectory structure (equivalent toandroid-test-app) - Copy HTML/JS UI from
android-test-app/app/src/main/assets/public/index.html - Adapt JavaScript to use iOS plugin methods
- Configure Info.plist with required permissions
- Implement AppDelegate with plugin setup
- Set up Xcode project/workspace
- Configure CocoaPods (if needed) or direct dependencies
- Create build script
scripts/build-ios-test-app.sh - Test Xcode GUI builds
- Test command-line builds via script
- Implement comprehensive logging
- Add Console.app integration
- Create debugging documentation
File Organization
New Files to Create
ios/Plugin/
├── DailyNotificationStorage.swift # Storage abstraction (new)
├── DailyNotificationScheduler.swift # Scheduler implementation (new)
├── DailyNotificationJWTManager.swift # JWT management (new)
├── EnhancedDailyNotificationFetcher.swift # Enhanced fetcher (new)
└── DailyNotificationRebootRecoveryManager.swift # Reboot recovery (new)
Files to Enhance
ios/Plugin/
├── DailyNotificationPlugin.swift # Add missing methods
├── DailyNotificationBackgroundTaskManager.swift # Enhance background tasks
├── DailyNotificationRollingWindow.swift # Enhance rolling window
├── DailyNotificationTTLEnforcer.swift # Enhance TTL enforcement
└── DailyNotificationETagManager.swift # Enhance ETag management
Test App Files to Create
test-apps/ios-test-app/ # New iOS test app (equivalent to android-test-app)
├── App/
│ ├── AppDelegate.swift # App delegate with plugin setup
│ ├── Info.plist # iOS permissions and config
│ ├── SceneDelegate.swift # Scene management (if needed)
│ └── Main.storyboard # Main storyboard (if needed)
├── App.xcodeproj/ # Xcode project
├── App.xcworkspace/ # Xcode workspace (if using CocoaPods)
├── Podfile # CocoaPods dependencies
└── www/ # Web assets (same as android-test-app)
├── index.html # Same UI as android-test-app
├── capacitor.config.json # Capacitor config
└── capacitor.plugins.json # Plugin registration
Build Scripts to Create
scripts/
└── build-ios-test-app.sh # iOS test app build script (new)
# Pattern: Similar to scripts/build-native.sh
# Features:
# - Check environment (xcodebuild, pod)
# - Install dependencies (pod install)
# - Build for simulator or device
# - Clear error messages and logging
Success Criteria
Functional Parity
- All Android
@PluginMethodmethods have iOS equivalents - All methods return same data structures as Android
- All methods handle errors consistently with Android
- All methods log consistently with Android
Platform Adaptations
- iOS uses appropriate iOS APIs (UNUserNotificationCenter, BGTaskScheduler)
- iOS respects iOS limits (64 notification limit, background execution limits)
- iOS provides iOS-specific features where appropriate (Background App Refresh)
Code Quality
- All code follows Swift best practices
- All code is documented with file-level and method-level comments
- All code includes error handling and logging
- All code is type-safe
Testing
- Unit tests cover all new methods
- Integration tests verify full pipeline
- Manual testing confirms real-world behavior
Test App
ios-test-appcreated with same UI asandroid-test-app- Test app uses iOS plugin implementation
- All permissions properly configured in Info.plist
- Build script
build-ios-test-app.shcreated and working - Build works via both Xcode GUI and command line
- Comprehensive logging accessible via Console.app
- Background task debugging tools available
Risks & Mitigations
Risk 1: iOS Background Execution Limitations
Risk: iOS background execution is more limited than Android
Mitigation:
- Use efficient processing algorithms
- Schedule next task immediately after completion
- Provide clear user guidance on Background App Refresh
Risk 2: iOS Notification Limits
Risk: iOS 64 notification limit may conflict with rolling window strategy
Mitigation:
- Implement smart rolling window that respects limits
- Prioritize today's notifications over tomorrow's
- Provide clear error messages when limits are reached
Risk 3: TypeScript Interface Compatibility
Risk: iOS implementation may not match TypeScript interface exactly
Mitigation:
- Test all methods against TypeScript interface
- Ensure return types match exactly
- Ensure error handling matches Android behavior
Risk 4: Platform-Specific Behavior Differences
Risk: iOS and Android may behave differently for same operations
Mitigation:
- Document all platform differences
- Provide platform-specific error messages where appropriate
- Test cross-platform compatibility
Timeline Estimate
Phase 1: Core Infrastructure
- Storage layer implementation
- Scheduler implementation (single daily schedule: one prefetch + one notification)
- Prefetch scheduled 5 minutes before notification time
- Background fetching enhancement (single daily prefetch, 5 minutes before notification)
- Core methods implementation
- iOS test app creation (ios-test-app)
- Build script creation (build-ios-test-app.sh)
- Testing on iOS Simulator
Test App Readiness: ✅ Ready for testing after Phase 1 completion
- Basic scheduling (one prefetch 5 minutes before + one notification per day)
- Core plugin methods functional
- Testable on iOS Simulator
Phase 2: Advanced Features
- Rolling window enhancement (expands beyond single daily schedule)
- TTL enforcement enhancement
- Exact alarm equivalent implementation
- Reboot recovery implementation
- Power management enhancement
- Testing on iOS Simulator
Test App Readiness: ✅ Ready for testing after Phase 2 completion
- Rolling window and advanced features functional
- Testable on iOS Simulator
Phase 3: TimeSafari Integration
- JWT management implementation
- ETag management enhancement
- Enhanced fetcher implementation
- Phase 1 methods implementation
- Testing on iOS Simulator
TimeSafari Integration Readiness: ✅ Library ready for TimeSafari integration after Phase 3 completion Test App Readiness: ✅ Ready for testing after Phase 3 completion
- TimeSafari integration features functional
- Testable on iOS Simulator
Phase 4: Background Coordination
- Background coordination implementation
- Lifecycle management implementation
- Coordination status implementation
- Testing on iOS Simulator
TimeSafari Integration Readiness: ✅ Full library ready for production TimeSafari integration after Phase 4 completion Test App Readiness: ✅ Ready for testing after Phase 4 completion
- Full background coordination functional
- Testable on iOS Simulator
Dependencies
External Dependencies
- Capacitor: iOS plugin framework
- UserNotifications: iOS notification framework
- BackgroundTasks: iOS background execution framework
- CoreData: iOS data persistence framework
Internal Dependencies
- TypeScript Interface: Must remain unchanged (
src/definitions.ts) - Android Implementation: Reference implementation (read-only)
- Existing iOS Components: Build upon existing Swift files
References
Android Implementation Files
src/android/DailyNotificationPlugin.java- Main plugin classsrc/android/DailyNotificationStorage.java- Storage layersrc/android/DailyNotificationScheduler.java- Schedulersrc/android/DailyNotificationFetcher.java- Background fetchingsrc/android/DailyNotificationDatabase.java- Database managementsrc/android/DailyNotificationRollingWindow.java- Rolling windowsrc/android/DailyNotificationExactAlarmManager.java- Exact alarmssrc/android/DailyNotificationRebootRecoveryManager.java- Reboot recoverysrc/android/DailyNotificationTTLEnforcer.java- TTL enforcementsrc/android/DailyNotificationETagManager.java- ETag managementsrc/android/DailyNotificationJWTManager.java- JWT managementsrc/android/EnhancedDailyNotificationFetcher.java- Enhanced fetcher
iOS Implementation Files
ios/Plugin/DailyNotificationPlugin.swift- Main plugin classios/Plugin/DailyNotificationDatabase.swift- Database (CoreData)ios/Plugin/DailyNotificationRollingWindow.swift- Rolling windowios/Plugin/DailyNotificationTTLEnforcer.swift- TTL enforcementios/Plugin/DailyNotificationETagManager.swift- ETag managementios/Plugin/DailyNotificationBackgroundTaskManager.swift- Background tasks
TypeScript Interface
src/definitions.ts- Complete TypeScript interface definition
Documentation
doc/implementation-roadmap.md- Implementation roadmapdoc/INTEGRATION_CHECKLIST.md- Integration checklistREADME.md- Project documentation
Competence Hooks
Why This Works
- Platform Parity: Matching Android functionality ensures consistent user experience across platforms
- Incremental Approach: Phased implementation reduces risk and allows for iterative testing
- Platform Adaptations: Using iOS-native APIs ensures optimal performance and reliability
Common Pitfalls
- Background Execution Limits: iOS background execution is more limited than Android - must design for efficiency
- Notification Limits: iOS 64 notification limit requires careful rolling window management
- Permission Model: iOS requires explicit permission requests - must handle gracefully
Next Skill Unlock
- iOS Background Execution: Understanding BGTaskScheduler and background execution patterns
- iOS Notification System: Deep dive into UNUserNotificationCenter and notification delivery guarantees
Teach-Back
Question: "How does iOS background execution differ from Android, and how does this affect the notification scheduling strategy?"
Expected Answer: iOS background execution is more limited (30 seconds for refresh tasks) and less reliable than Android WorkManager. This requires efficient processing, immediate next-schedule after completion, and fallback strategies for when background execution fails.
Collaboration Hooks
Discussion Points
- Platform Differences: How should we handle platform-specific behavior differences in error messages and user guidance?
- Testing Strategy: What level of cross-platform testing is needed to ensure parity?
- Performance: How do we ensure iOS implementation performs as well as Android?
Review Points
- Code Review: All new iOS code should be reviewed against Android implementation for functional parity
- Architecture Review: iOS component architecture should be reviewed for maintainability
- Testing Review: Test coverage should be reviewed for completeness
Stakeholders
- iOS Developer: Primary implementer
- Android Developer: Reference implementation owner (consultation)
- TypeScript Developer: Interface maintainer (consultation)
- QA: Testing and validation
Decision Log
2025-11-13: Directive Created
Decision: Create comprehensive directive for iOS Android parity implementation
Rationale: Need clear plan for upgrading iOS while preserving Android and TypeScript interface
Status: ✅ Approved for implementation
Status: 🎯 READY FOR IMPLEMENTATION
Next Steps: Begin Phase 1 implementation after directive approval