Skip to main content
Learn how to view logs from iOS devices and simulators for debugging React Native applications.

Overview

iOS logging can be viewed through multiple tools including Console.app, Xcode, command-line utilities, and third-party applications.

Quick Start

View Logs from Simulator

xcrun simctl spawn booted log stream --predicate 'processImagePath endswith "YourApp"'

View Logs from Device

idevicesyslog
Or use Console.app (macOS built-in application).

Using Console.app

Console.app is macOS’s built-in log viewer.
1

Open Console.app

  • Press Cmd+Space and type “Console”
  • Or find it in /Applications/Utilities/Console.app
2

Select device

  • Connected devices appear in the sidebar
  • Select your iPhone/iPad or Simulator
3

Filter logs

In the search bar, enter:
  • Process: YourApp
  • Category: ReactNativeJS
  • Or custom filter expressions

Useful Filters

  • Your app only: process:"YourApp"
  • React Native: category:"ReactNativeJS"
  • Errors only: level:error
  • Combined: process:"YourApp" AND level:error

Using Xcode

Xcode provides integrated log viewing.
1

Open project

open ios/YourApp.xcworkspace
2

Run app

  • Press Cmd+R or click Run button
  • App builds and launches
3

View logs

  • Open Debug area (Cmd+Shift+Y)
  • Logs appear in the console pane
  • Click filter icon for options

Xcode Console Features

  • Filter by level: Error, Warning, Info, Debug
  • Search: Use search bar to find specific messages
  • Clear: Click trash icon to clear console
  • Export: Right-click to save logs

Command Line Tools

Simulator Logs

Basic Stream

xcrun simctl spawn booted log stream
Shows all simulator logs (very verbose).

Filter by Process

xcrun simctl spawn booted log stream --predicate 'processImagePath endswith "YourApp"'

Filter by Category

xcrun simctl spawn booted log stream --predicate 'category == "ReactNativeJS"'

Filter by Level

xcrun simctl spawn booted log stream --level debug
Levels: default, info, debug, error, fault

Multiple Filters

xcrun simctl spawn booted log stream --predicate 'processImagePath endswith "YourApp" AND level >= "error"'

Device Logs

Using idevicesyslog

Install libimobiledevice:
brew install libimobiledevice
View logs:
idevicesyslog
Filter:
idevicesyslog | grep "YourApp"

Using log Command (macOS Catalina+)

log stream --device --predicate 'process == "YourApp"'

Save Logs to File

# Simulator
xcrun simctl spawn booted log stream > simulator-logs.txt

# Device
idevicesyslog > device-logs.txt

JavaScript Console Logs

console.log()

console.log('Hello from JavaScript!');
Appears as:
[ReactNativeJS] Hello from JavaScript!

console.warn()

console.warn('Warning message');
Shows yellow warning box in app and appears in logs.

console.error()

console.error('Error message');
Shows red error screen in app and appears in logs.

console.debug()

console.debug('Debug info');

Formatted Logging

console.log('User:', {name: 'John', age: 30});
console.log('Numbers: %d, %d, %d', 1, 2, 3);
console.log('%c Styled!', 'color: blue; font-weight: bold');

Native Logs

Objective-C

#import <React/RCTLog.h>

RCTLog(@"Message from Objective-C");
RCTLogInfo(@"Info message");
RCTLogWarn(@"Warning message");
RCTLogError(@"Error message");

Swift

import React

RCTLog("Message from Swift")
RCTLogInfo("Info message")
RCTLogWarn("Warning message")
RCTLogError("Error message")

NSLog

NSLog(@"Traditional iOS log: %@", someValue);
NSLog("Traditional iOS log: %@", someValue)

os_log (Modern)

#import <os/log.h>

os_log_t log = os_log_create("com.yourapp", "MyCategory");
os_log_info(log, "Info message");
os_log_error(log, "Error message");
import os.log

let log = OSLog(subsystem: "com.yourapp", category: "MyCategory")
os_log("Info message", log: log, type: .info)
os_log("Error message", log: log, type: .error)

React Native Debugger

Install

brew install --cask react-native-debugger

Use

  1. Start React Native Debugger
  2. Open developer menu in app (Cmd+D)
  3. Select “Debug”
  4. Logs appear in debugger console
Features:
  • Console logs
  • Network inspector
  • React DevTools
  • Redux DevTools

Flipper

Facebook’s debugging platform for React Native.

Install

brew install --cask flipper

Setup

Follow Flipper setup guide.

Features

  • Logs: Real-time log viewer
  • Layout Inspector: View hierarchy
  • Network: HTTP/HTTPS requests
  • Databases: Browse app databases
  • Crash Reporter: Native crash reports
  • React DevTools: Component inspector

Safari Web Inspector

For debugging JSCore (non-Hermes):
1

Enable Web Inspector

On device: Settings > Safari > Advanced > Web Inspector
2

Open Safari

On Mac, open Safari
3

Connect

Develop menu > [Your Device] > JSContext
4

Debug

Use Safari DevTools console
This only works with JavaScriptCore, not Hermes.

Crash Logs

View Recent Crashes

From Xcode

  1. Window > Devices and Simulators
  2. Select device
  3. Click View Device Logs
  4. Find crash reports

From Finder

Simulator crashes:
open ~/Library/Logs/DiagnosticReports/
Device crashes (synced):
open ~/Library/Logs/CrashReporter/MobileDevice/

Symbolicate Crash Reports

# Export archive from Xcode
# Locate .dSYM file
# Use symbolicatecrash

export DEVELOPER_DIR="/Applications/Xcode.app/Contents/Developer"

/Applications/Xcode.app/Contents/SharedFrameworks/DVTFoundation.framework/Versions/A/Resources/symbolicatecrash \
  crash.log \
  YourApp.app.dSYM \
  > symbolicated.crash

Performance Monitoring

Instruments

Xcode’s performance analysis tool:
  1. In Xcode: Product > Profile (Cmd+I)
  2. Choose template:
    • Time Profiler: CPU usage
    • Allocations: Memory usage
    • Leaks: Memory leaks
    • Network: Network activity
  3. Record and analyze

React DevTools Profiler

  1. Open React Native Debugger or Flipper
  2. Go to Profiler tab
  3. Click Record
  4. Interact with app
  5. Stop and analyze

Advanced Filtering

Predicate Syntax

Used with log stream:
# Process name
log stream --predicate 'process == "YourApp"'

# Category
log stream --predicate 'category == "ReactNativeJS"'

# Level
log stream --predicate 'level >= "error"'

# Message content
log stream --predicate 'eventMessage contains "error"'

# Subsystem
log stream --predicate 'subsystem == "com.yourapp"'

# Combined
log stream --predicate 'process == "YourApp" AND level >= "error"'

Grep Patterns

# Case insensitive
idevicesyslog | grep -i "error"

# Multiple patterns
idevicesyslog | grep -E "error|warning"

# Exclude
idevicesyslog | grep -v "noise"

# Highlight
idevicesyslog | grep --color=always "YourApp"

Multiple Devices

List Simulators

xcrun simctl list devices

Target Specific Simulator

xcrun simctl spawn <UDID> log stream

List Devices

idevice_id -l

Target Specific Device

idevicesyslog -u <UDID>

Log Levels

iOS uses these log levels (os_log):
  • Default: Standard log messages
  • Info: Informational messages
  • Debug: Debug messages (not persisted by default)
  • Error: Error messages
  • Fault: Critical errors

Configure Log Level

In code:
os_log("Message", log: log, type: .default)
os_log("Message", log: log, type: .info)
os_log("Message", log: log, type: .debug)
os_log("Message", log: log, type: .error)
os_log("Message", log: log, type: .fault)

Troubleshooting

No Logs Appearing

Solution:
  1. Verify device/simulator is selected
  2. Check filter settings
  3. Try restarting app
  4. Clear and restart

Too Verbose

Solution: Use specific filters:
log stream --predicate 'process == "YourApp"' --level error

Can’t Find Crash Logs

Solution:
  1. Xcode > Window > Devices and Simulators
  2. Select device
  3. View Device Logs
  4. Filter by date/process

idevicesyslog Not Working

Solution:
# Reinstall libimobiledevice
brew uninstall libimobiledevice
brew install libimobiledevice

# Or try ios-deploy
npm install -g ios-deploy
ios-deploy -c

Best Practices

if (__DEV__) {
  console.log('Development only');
}
console.warn('User should see this warning');
console.error('Critical error');
let log = OSLog(subsystem: "com.yourapp", category: "Networking")
os_log("Request failed", log: log, type: .error)
Use preprocessor directives:
#ifdef DEBUG
    NSLog(@"Debug info");
#endif
console.log('[Auth]', 'User logged in:', {userId: 123});

Production Logging

For production apps, use error tracking services:
  • Sentry: @sentry/react-native
  • Bugsnag: @bugsnag/react-native
  • Firebase Crashlytics: @react-native-firebase/crashlytics
Example with Sentry:
import * as Sentry from '@sentry/react-native';

Sentry.init({
  dsn: 'YOUR_DSN',
});

// Logs automatically sent to Sentry
console.error('This will be tracked');
Sentry.captureException(new Error('Manual error'));

Next Steps

Run iOS

Build and run your iOS app

Android Logs

View Android device logs

Debugging

Complete debugging guide

Troubleshooting

Common issues and solutions

Build docs developers (and LLMs) love