Implement UNUserNotificationCenterDelegate in AppDelegate to display notifications when app is in foreground. Add visual feedback indicator in test app UI to confirm notification delivery. Changes: - AppDelegate: Conform to UNUserNotificationCenterDelegate protocol - AppDelegate: Implement willPresent and didReceive delegate methods - AppDelegate: Set delegate at multiple lifecycle points to ensure it's always active (immediate, after Capacitor init, on app active) - UI: Add notification received indicator in status card - UI: Add periodic check for notification delivery (every 5 seconds) - UI: Add instructions on where to look for notification banner - Docs: Add IOS_LOGGING_GUIDE.md for debugging iOS logs This fixes the issue where scheduled notifications were not visible when the app was in the foreground. The delegate method now properly presents notifications with banner, sound, and badge options. Verified working: Logs show delegate method called successfully when notification fires, with proper presentation options set.
8.1 KiB
iOS Logging Guide - How to Check Logs for Errors
Purpose: Quick reference for viewing iOS app logs during development and debugging
Last Updated: 2025-11-15
Status: 🎯 ACTIVE - Reference guide for iOS debugging
Quick Start
Most Common Methods (in order of ease):
- Xcode Console (when app is running in Xcode) - Easiest
- Console.app (macOS system console) - Good for background logs
- Command-line (
xcrun simctl) - Best for automation/scripts
Method 1: Xcode Console (Recommended for Development)
When to use: App is running in Xcode (simulator or device)
Steps:
- Open Xcode and run your app (Cmd+R)
- Open Debug Area:
- Press Cmd+Shift+Y (or View → Debug Area → Activate Console)
- Or click the bottom panel icon in Xcode
- Filter logs:
- Click the search box at bottom of console
- Type:
DNP-orDailyNotificationorError - Press Enter
Filter Examples:
DNP-PLUGIN # Plugin operations
DNP-FETCH # Background fetch operations
DNP-SCHEDULER # Scheduling operations
DNP-STORAGE # Storage operations
Error # All errors
Copy-Paste Commands (LLDB Console):
When app is running, you can also use LLDB commands in Xcode console:
// Check pending notifications
po UNUserNotificationCenter.current().pendingNotificationRequests()
// Check permission status
po await UNUserNotificationCenter.current().notificationSettings()
// Manually trigger BGTask (simulator only)
e -l objc -- (void)[[BGTaskScheduler sharedScheduler] _simulateLaunchForTaskWithIdentifier:@"com.timesafari.dailynotification.fetch"]
Method 2: Console.app (macOS System Console)
When to use: App is running in background, or you want to see system-level logs
Steps:
-
Open Console.app:
- Press Cmd+Space (Spotlight)
- Type:
Console - Press Enter
- Or: Applications → Utilities → Console
-
Select Device/Simulator:
- In left sidebar, expand "Devices"
- Select your simulator or connected device
- Or select "All Logs" for system-wide logs
-
Filter logs:
- Click search box (top right)
- Type:
DNP-orcom.timesafari.dailynotification - Press Enter
Filter by Subsystem (Structured Logging):
The plugin uses structured logging with subsystems:
com.timesafari.dailynotification.plugin # Plugin operations
com.timesafari.dailynotification.fetch # Fetch operations
com.timesafari.dailynotification.scheduler # Scheduling operations
com.timesafari.dailynotification.storage # Storage operations
To filter by subsystem:
- In Console.app search:
subsystem:com.timesafari.dailynotification
Method 3: Command-Line (xcrun simctl)
When to use: Automation, scripts, or when Xcode/Console.app aren't available
Stream Live Logs (Simulator):
# Stream all logs from booted simulator
xcrun simctl spawn booted log stream
# Stream only plugin logs (filtered)
xcrun simctl spawn booted log stream --predicate 'subsystem == "com.timesafari.dailynotification"'
# Stream with DNP- prefix filter
xcrun simctl spawn booted log stream | grep "DNP-"
Save Logs to File:
# Save all logs to file
xcrun simctl spawn booted log stream > device.log 2>&1
# Save filtered logs
xcrun simctl spawn booted log stream --predicate 'subsystem == "com.timesafari.dailynotification"' > plugin.log 2>&1
# Then analyze with grep
grep -E "\[DNP-(FETCH|SCHEDULER|PLUGIN)\]" device.log
View Recent Logs (Not Streaming):
# Show recent logs (last 100 lines)
xcrun simctl spawn booted log show --last 1m | grep "DNP-"
# Show logs for specific time range
xcrun simctl spawn booted log show --start "2025-11-15 10:00:00" --end "2025-11-15 11:00:00" | grep "DNP-"
Physical Device Logs:
# List connected devices
xcrun devicectl list devices
# Stream logs from physical device (requires device UDID)
xcrun devicectl device process launch --device <UDID> com.timesafari.dailynotification.test
# Or use Console.app for physical devices (easier)
Method 4: Validate Log Sequence (Automated)
When to use: Testing prefetch cycles, verifying complete execution
Using Validation Script:
# From log file
./scripts/validate-ios-logs.sh device.log
# From live stream
xcrun simctl spawn booted log stream --predicate 'subsystem == "com.timesafari.dailynotification"' | ./scripts/validate-ios-logs.sh
# From filtered grep
grep -E "\[DNP-(FETCH|SCHEDULER|PLUGIN)\]" device.log | ./scripts/validate-ios-logs.sh
See: scripts/validate-ios-logs.sh for complete validation script
Common Log Prefixes
Plugin Logs (look for these):
| Prefix | Meaning | Example |
|---|---|---|
[DNP-PLUGIN] |
Main plugin operations | [DNP-PLUGIN] configure() called |
[DNP-FETCH] |
Background fetch operations | [DNP-FETCH] BGTask handler invoked |
[DNP-SCHEDULER] |
Notification scheduling | [DNP-SCHEDULER] Scheduling notification |
[DNP-STORAGE] |
Storage/DB operations | [DNP-STORAGE] Persisted schedule |
[DNP-DEBUG] |
Debug diagnostics | [DNP-DEBUG] Plugin class found |
Error Indicators:
Error:- System errorsFailed:- Operation failures❌- Visual error markers in logs⚠️- Warning markers
Troubleshooting Common Issues
Issue: No logs appearing
Solutions:
- Check app is running: App must be launched to generate logs
- Check filter: Remove filters to see all logs
- Check log level: Some logs may be at debug level only
- Restart logging: Close and reopen Console.app or restart log stream
Issue: Too many logs (noise)
Solutions:
- Use specific filters:
DNP-instead ofDailyNotification - Filter by subsystem:
subsystem:com.timesafari.dailynotification - Use time range: Only show logs from last 5 minutes
- Use validation script: Automatically filters for important events
Issue: Can't see background task logs
Solutions:
- Use Console.app: Background tasks show better in system console
- Check Background App Refresh: Must be enabled for BGTask logs
- Use log stream:
xcrun simctl spawn booted log streamshows all logs - Check predicate: Use
--predicateto filter specific subsystems
Issue: Physical device logs not showing
Solutions:
- Use Console.app: Easiest for physical devices
- Check device connection: Device must be connected and trusted
- Check provisioning: Device must be provisioned for development
- Use Xcode: Xcode → Window → Devices and Simulators → View Device Logs
Quick Reference Commands
Copy-Paste Ready Commands:
# Stream plugin logs (simulator)
xcrun simctl spawn booted log stream --predicate 'subsystem == "com.timesafari.dailynotification"'
# Save logs to file
xcrun simctl spawn booted log stream > device.log 2>&1
# View recent errors
xcrun simctl spawn booted log show --last 5m | grep -i "error\|failed\|DNP-"
# Validate log sequence
grep -E "\[DNP-(FETCH|SCHEDULER|PLUGIN)\]" device.log | ./scripts/validate-ios-logs.sh
# Check app logs only
xcrun simctl spawn booted log stream --predicate 'process == "App"'
Log Levels and Filtering
iOS Log Levels:
- Default: Shows Info, Error, Fault
- Debug: Shows Debug, Info, Error, Fault
- Error: Shows Error, Fault only
To see debug logs:
- In Xcode: Product → Scheme → Edit Scheme → Run → Arguments → Environment Variables
- Add:
OS_ACTIVITY_MODE=disable(shows all logs including debug)
Or use Console.app:
- Action menu → Include Info Messages
- Action menu → Include Debug Messages
References
- Testing Guide:
doc/test-app-ios/IOS_PREFETCH_TESTING.md- Comprehensive testing procedures - Test App Requirements:
doc/test-app-ios/IOS_TEST_APP_REQUIREMENTS.md- Debugging section - Validation Script:
scripts/validate-ios-logs.sh- Automated log sequence validation - Main Directive:
doc/directives/0003-iOS-Android-Parity-Directive.md- Implementation details
Status: 🎯 READY FOR USE
Maintainer: Matthew Raymer