docs(ios): update test app docs with recent implementation details

Updated iOS test app documentation to reflect recent implementation work:
channel methods, permission methods, BGTaskScheduler simulator limitation,
and plugin discovery troubleshooting.

Changes:
- Added channel methods (isChannelEnabled, openChannelSettings) to UI mapping
- Fixed permission method name (requestPermissions → requestNotificationPermissions)
- Added checkPermissionStatus to UI mapping
- Added Channel Management section explaining iOS limitations
- Added BGTaskScheduler simulator limitation documentation (Code=1 is expected)
- Added plugin discovery troubleshooting section (CAPBridgedPlugin conformance)
- Added permission and channel methods to behavior classification table
- Updated Known OS Limitations with simulator-specific BGTaskScheduler behavior

Files modified:
- doc/test-app-ios/IOS_TEST_APP_REQUIREMENTS.md: UI mapping, debugging scenarios
- doc/test-app-ios/IOS_PREFETCH_TESTING.md: Known limitations, behavior classification
This commit is contained in:
Matthew
2025-11-16 21:53:56 -08:00
parent 6d25cdd033
commit d7a2dbb9fd
2 changed files with 42 additions and 5 deletions

View File

@@ -301,11 +301,22 @@ When you see `[DNP-FETCH] Fetch success (status=200, bytes=1234, ttl=86400)`, th
**Critical:** These are iOS system limitations, not plugin bugs. If these conditions occur, it is **not a plugin bug**; confirm logs and document behavior.
**BGTaskScheduler Simulator Limitation:**
- **BGTaskSchedulerErrorDomain Code=1 (notPermitted) is EXPECTED on simulator**
- BGTaskScheduler doesn't work reliably on iOS Simulator - this is a known iOS limitation
- Background fetch scheduling will fail on simulator with Code=1 error
- **This is NOT a plugin bug** - notification scheduling still works correctly
- Prefetch won't run on simulator, but will work on real devices with Background App Refresh enabled
- Error handling logs: "Background fetch scheduling failed (expected on simulator)"
- **Testing:** Use Xcode → Debug → Simulate Background Fetch for simulator testing
- **See also:** `doc/directives/0003-iOS-Android-Parity-Directive.md` for implementation details
**iOS may NOT run BGTasks if:**
- App has been force-quit by the user (iOS won't run BGTask for force-quit apps)
- Background App Refresh is disabled in Settings → [Your App]
- Device is in Low Power Mode and idle
- Device battery is critically low
- **On Simulator:** BGTaskScheduler generally doesn't work (Code=1 error is expected)
**iOS timing heuristics:**
- iOS may delay or batch tasks; prefetch might run **much later** than `earliestBeginDate` (up to 15+ minutes)
@@ -432,6 +443,7 @@ When everything is wired correctly, one full cycle should produce:
- Check BGTaskScheduler submission succeeded
- Verify `earliestBeginDate` is at least 1 minute in future
- Check for BGTaskScheduler errors in logs
- **On Simulator:** BGTaskSchedulerErrorDomain Code=1 (notPermitted) is expected - see "Known OS Limitations"
**If you see BGTask scheduled but not persisted:**
- Check database write operations
@@ -522,6 +534,8 @@ Testable matrix of deterministic vs heuristic behavior:
|--------|-------------------|----------------|---------|-------|
| A | `BGTaskScheduler.shared.register` | Yes | Sim + Dev | Registration must always log & succeed/fail deterministically |
| A | `configure()`, `getLastNotification()`, `cancelAllNotifications()`, `getNotificationStatus()`, `updateSettings()` | Yes | Sim + Dev | Logic & I/O-only, no timing dependencies |
| A | `checkPermissionStatus()`, `requestNotificationPermissions()` | Yes | Sim + Dev | Permission state reading and requests, deterministic |
| A | `isChannelEnabled(channelId?)`, `openChannelSettings(channelId?)` | Yes | Sim + Dev | Channel status and settings (iOS: app-wide, not per-channel) |
| A | `getBatteryStatus()`, `getPowerState()`, `getRollingWindowStats()` | Yes | Sim + Dev | State reading, deterministic |
| A | `testJWTGeneration()`, `testEndorserAPI()` | Yes | Sim + Dev | API call logic, deterministic |
| A | Fetch function logic (HTTP calls, DB writes, JSON parsing) | Yes | Sim + Dev | Code path is deterministic |

View File

@@ -69,6 +69,7 @@ The iOS test app **MUST** use the same HTML/JS UI as the Android test app to ens
- Test notification button
- Check permissions button
- Request permissions button
- Channel management buttons (Check Channel Status, Open Channel Settings)
- Status display area
- Log output area (optional, for debugging)
@@ -86,12 +87,17 @@ The test app UI must support:
- Check permissions button
- Show ✅/❌ indicators for each permission
3. **Notification Testing**
3. **Channel Management** (iOS parity with Android)
- Check channel status button (iOS: checks app-wide notification authorization)
- Open channel settings button (iOS: opens app Settings, not per-channel)
- Note: iOS doesn't have per-channel control like Android; these methods provide app-wide equivalents
4. **Notification Testing**
- Schedule test notification button
- Display scheduled time
- Show notification status
4. **Status Display**
5. **Status Display**
- Show last notification time
- Show pending notification count
- Display error messages if any
@@ -101,12 +107,14 @@ The test app UI must support:
| UI Element / Button | Plugin Method / API Call | Notes |
|---------------------|-------------------------|-------|
| "Check Plugin Status" | `DailyNotification.configure()` or status call | Verify plugin load & config |
| "Check Permissions" | `getNotificationStatus()` | Maps to permission state |
| "Request Permissions" | `requestPermissions()` | Drives iOS UNUserNotificationCenter |
| "Check Permissions" | `checkPermissionStatus()` | Returns current notification permission status |
| "Request Permissions" | `requestNotificationPermissions()` | Requests notification permissions (shows system dialog) |
| "Schedule Test Notification" | `scheduleDailyNotification()` | Should schedule prefetch + notify |
| "Show Last Notification" | `getLastNotification()` | Uses deterministic path (Bucket A) |
| "Cancel All Notifications" | `cancelAllNotifications()` | Uses deterministic path (Bucket A) |
| "Get Notification Status" | `getNotificationStatus()` | Uses deterministic path (Bucket A) |
| "Check Channel Status" | `isChannelEnabled(channelId?)` | Checks if notifications enabled (iOS: app-wide) |
| "Open Channel Settings" | `openChannelSettings(channelId?)` | Opens notification settings (iOS: app Settings) |
**See `IOS_PREFETCH_TESTING.md` Behavior Classification for deterministic vs heuristic methods.**
@@ -291,7 +299,22 @@ e -l objc -- (void)[[BGTaskScheduler sharedScheduler] _simulateLaunchForTaskWith
- Check notification category registered
- **See also:** `IOS_PREFETCH_TESTING.md Log Checklist: Section 4`
3. **Build Failures:**
3. **BGTaskScheduler Fails on Simulator:**
- **Expected Behavior:** BGTaskSchedulerErrorDomain Code=1 (notPermitted) is **normal on simulator**
- BGTaskScheduler doesn't work reliably on simulator - this is an iOS limitation, not a plugin bug
- Notification scheduling still works; prefetch won't run on simulator but will work on real devices
- Error handling logs clear message: "Background fetch scheduling failed (expected on simulator)"
- **See also:** `IOS_PREFETCH_TESTING.md Known OS Limitations` for details
- **Testing:** Use Xcode → Debug → Simulate Background Fetch for simulator testing
4. **Plugin Not Discovered:**
- Check plugin class conforms to `CAPBridgedPlugin` protocol (required for Capacitor discovery)
- Verify `@objc extension DailyNotificationPlugin: CAPBridgedPlugin` exists in plugin code
- Check plugin framework is force-loaded in AppDelegate before Capacitor initializes
- Verify `pluginMethods` array includes all `@objc` methods
- **See also:** `doc/directives/0003-iOS-Android-Parity-Directive.md Plugin Discovery Issue` for detailed troubleshooting
5. **Build Failures:**
- Run `pod install`
- Clean build folder (Cmd+Shift+K)
- Verify Capacitor plugin path