# 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):** 1. **Xcode Console** (when app is running in Xcode) - Easiest 2. **Console.app** (macOS system console) - Good for background logs 3. **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: 1. **Open Xcode** and run your app (Cmd+R) 2. **Open Debug Area:** - Press **Cmd+Shift+Y** (or View → Debug Area → Activate Console) - Or click the bottom panel icon in Xcode 3. **Filter logs:** - Click the search box at bottom of console - Type: `DNP-` or `DailyNotification` or `Error` - 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: ```swift // 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: 1. **Open Console.app:** - Press **Cmd+Space** (Spotlight) - Type: `Console` - Press Enter - Or: Applications → Utilities → Console 2. **Select Device/Simulator:** - In left sidebar, expand "Devices" - Select your simulator or connected device - Or select "All Logs" for system-wide logs 3. **Filter logs:** - Click search box (top right) - Type: `DNP-` or `com.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): ```bash # 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: ```bash # 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): ```bash # 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: ```bash # List connected devices xcrun devicectl list devices # Stream logs from physical device (requires device UDID) xcrun devicectl device process launch --device 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: ```bash # 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 errors - `Failed:` - Operation failures - `❌` - Visual error markers in logs - `⚠️` - Warning markers --- ## Troubleshooting Common Issues ### Issue: No logs appearing **Solutions:** 1. **Check app is running:** App must be launched to generate logs 2. **Check filter:** Remove filters to see all logs 3. **Check log level:** Some logs may be at debug level only 4. **Restart logging:** Close and reopen Console.app or restart log stream ### Issue: Too many logs (noise) **Solutions:** 1. **Use specific filters:** `DNP-` instead of `DailyNotification` 2. **Filter by subsystem:** `subsystem:com.timesafari.dailynotification` 3. **Use time range:** Only show logs from last 5 minutes 4. **Use validation script:** Automatically filters for important events ### Issue: Can't see background task logs **Solutions:** 1. **Use Console.app:** Background tasks show better in system console 2. **Check Background App Refresh:** Must be enabled for BGTask logs 3. **Use log stream:** `xcrun simctl spawn booted log stream` shows all logs 4. **Check predicate:** Use `--predicate` to filter specific subsystems ### Issue: Physical device logs not showing **Solutions:** 1. **Use Console.app:** Easiest for physical devices 2. **Check device connection:** Device must be connected and trusted 3. **Check provisioning:** Device must be provisioned for development 4. **Use Xcode:** Xcode → Window → Devices and Simulators → View Device Logs --- ## Quick Reference Commands ### Copy-Paste Ready Commands: ```bash # 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