Files
gh-daispacy-py-claude-marke…/skills/instruments/examples.md
2025-11-29 18:17:22 +08:00

21 KiB

XCTrace & Instruments Examples for iOS project

Quick Reference - Working Commands

These commands have been tested and verified to work correctly:

# Get device UUID (always required)
DEVICE_UUID="F464E766-555C-4B95-B8CC-763702A70791"  # iPhone 17 Pro
xcrun simctl list devices available | grep "iPhone"

# App Launch Profiling (most common use case)
xcrun simctl uninstall $DEVICE_UUID <bundle id>
xcrun simctl install $DEVICE_UUID /Users/daipham/Library/Developer/Xcode/DerivedData/<app name>/Build/Products/Release-iphonesimulator/<app name>.app
sleep 2
xcrun xctrace record --template "App Launch" --device $DEVICE_UUID \
  --launch -- /Users/daipham/Library/Developer/Xcode/DerivedData/<app name>/Build/Products/Release-iphonesimulator/<app name>.app 2>&1

# Find generated trace file
ls -lt *.trace | head -1

# Open in Instruments for analysis
open -a Instruments.app Launch_<app name>*.trace

XCTrace Overview

xcrun xctrace is the modern command-line interface for Instruments profiling. It replaces the deprecated instruments command and provides more reliable automation capabilities.

Available Templates

Run xcrun xctrace list templates to see all available templates:

Standard Templates

  • Activity Monitor: General system activity monitoring
  • Allocations: Memory allocation tracking
  • Animation Hitches: UI animation performance issues
  • App Launch: App startup performance analysis
  • Audio System Trace: Audio subsystem performance
  • CPU Counters: Hardware performance counters
  • CPU Profiler: CPU usage profiling
  • Core ML: Machine learning model performance
  • Data Persistence: Core Data and file I/O analysis
  • File Activity: File system operations
  • Game Memory: Game-specific memory analysis
  • Game Performance: Game-specific performance metrics
  • Game Performance Overview: High-level game metrics
  • Leaks: Memory leak detection
  • Logging: System and app logging analysis
  • Metal System Trace: GPU performance analysis
  • Network: Network activity monitoring
  • Power Profiler: Energy consumption analysis
  • Processor Trace: Low-level CPU tracing
  • RealityKit Trace: AR/VR performance analysis
  • Swift Concurrency: Swift async/await performance
  • SwiftUI: SwiftUI-specific performance analysis
  • System Trace: System-wide performance analysis
  • Tailspin: System responsiveness analysis
  • Time Profiler: CPU time profiling

Device Management

List Available Devices

# List all devices (physical and simulators)
xcrun xctrace list devices

# List only simulators with UUIDs (RECOMMENDED)
xcrun simctl list devices available | grep "iPhone"

Current Available Devices for

  • Simulators: iPhone 16 Pro, iPhone 16, iPhone 17 Pro (F464E766-555C-4B95-B8CC-763702A70791), iPad variants, etc.

⚠️ IMPORTANT: Always Use Device UUID, Not Name

Device names can be ambiguous. Always use the device UUID for reliable automation:

# ❌ WRONG - Ambiguous device name
xcrun xctrace record --template "App Launch" --device "iPhone 16 Pro" ...

# ✅ CORRECT - Use UUID
xcrun xctrace record --template "App Launch" --device F464E766-555C-4B95-B8CC-763702A70791 ...

Basic XCTrace Commands

1. App Launch Performance Analysis

# ✅ CORRECT METHOD - Clean state, use UUID, proper app path handling
# Step 1: Get device UUID
DEVICE_UUID="F464E766-555C-4B95-B8CC-763702A70791"  # iPhone 17 Pro

# Step 2: Clean up any existing app installations (IMPORTANT to avoid ambiguity)
xcrun simctl uninstall $DEVICE_UUID <bundle id>

# Step 3: Install fresh app build
xcrun simctl install $DEVICE_UUID /Users/daipham/Library/Developer/Xcode/DerivedData/<app name>/Build/Products/Release-iphonesimulator/<app name>.app

# Step 4: Wait for installation to complete
sleep 2

# Step 5: Profile app launch
xcrun xctrace record --template "App Launch" \
  --device $DEVICE_UUID \
  --launch -- /Users/daipham/Library/Developer/Xcode/DerivedData/<app name>/Build/Products/Release-iphonesimulator/<app name>.app \
  --output ~/Desktop/<app name>_launch_analysis.trace 2>&1

# Note: Trace file will be saved with auto-generated name in current directory
# Example: Launch_<app name>.app_2025-10-30_3.55.40 PM_39E6A410.trace

Alternative: Complete Clean State (Most Reliable)

# For most reliable results, completely erase and reboot simulator
DEVICE_UUID="F464E766-555C-4B95-B8CC-763702A70791"

xcrun simctl shutdown $DEVICE_UUID
xcrun simctl erase $DEVICE_UUID
xcrun simctl boot $DEVICE_UUID
xcrun simctl install $DEVICE_UUID /Users/daipham/Library/Developer/Xcode/DerivedData/<app name>/Build/Products/Release-iphonesimulator/<app name>.app
sleep 2
xcrun xctrace record --template "App Launch" --device $DEVICE_UUID \
  --launch -- /Users/daipham/Library/Developer/Xcode/DerivedData/<app name>/Build/Products/Release-iphonesimulator/<app name>.app \
  2>&1

2. Memory Allocation Tracking

# ✅ Track memory allocations during app usage
DEVICE_UUID="F464E766-555C-4B95-B8CC-763702A70791"

# Option 1: Attach to running app
xcrun xctrace record --template "Allocations" \
  --device $DEVICE_UUID \
  --attach "<app name>" \
  --time-limit 5m

# Option 2: Launch and track from start
xcrun xctrace record --template "Allocations" \
  --device $DEVICE_UUID \
  --launch -- /Users/daipham/Library/Developer/Xcode/DerivedData/<app name>/Build/Products/Release-iphonesimulator/<app name>.app \
  --time-limit 5m

3. CPU Time Profiling

# ✅ Profile CPU usage
DEVICE_UUID="F464E766-555C-4B95-B8CC-763702A70791"

xcrun xctrace record --template "Time Profiler" \
  --device $DEVICE_UUID \
  --attach "<app name>" \
  --time-limit 2m

4. Memory Leak Detection

# ✅ Detect memory leaks
DEVICE_UUID="F464E766-555C-4B95-B8CC-763702A70791"

xcrun xctrace record --template "Leaks" \
  --device $DEVICE_UUID \
  --attach "<app name>" \
  --time-limit 3m

5. Network Activity Monitoring

# Monitor network requests and responses
xcrun xctrace record --template "Network" \
  --device "iPhone 16 Pro Simulator (18.5)" \
  --attach "<app name>" \
  --output ~/Desktop/<app name>_network_analysis.trace \
  --time-limit 5m

6. SwiftUI Performance Analysis

# Analyze SwiftUI performance (if using SwiftUI)
xcrun xctrace record --template "SwiftUI" \
  --device "iPhone 16 Pro Simulator (18.5)" \
  --attach "<app name>" \
  --output ~/Desktop/<app name>_swiftui_analysis.trace \
  --time-limit 2m

7. Animation Performance

# Detect animation hitches and performance issues
xcrun xctrace record --template "Animation Hitches" \
  --device "iPhone 16 Pro Simulator (18.5)" \
  --attach "<app name>" \
  --output ~/Desktop/<app name>_animation_analysis.trace \
  --time-limit 3m

8. Power/Energy Analysis

# Analyze energy consumption
xcrun xctrace record --template "Power Profiler" \
  --device "iPhone 16 Pro Simulator (18.5)" \
  --attach "<app name>" \
  --output ~/Desktop/<app name>_power_analysis.trace \
  --time-limit 10m

Advanced Usage

Recording All Processes

# Record system-wide performance
xcrun xctrace record --template "System Trace" \
  --device "iPhone 16 Pro Simulator (18.5)" \
  --all-processes \
  --output ~/Desktop/<app name>_system_trace.trace \
  --time-limit 1m

Custom Environment Variables

# Launch with custom environment variables
xcrun xctrace record --template "Time Profiler" \
  --device "iPhone 16 Pro Simulator (18.5)" \
  --env "LOG_LEVEL=verbose" \
  --launch -- "/path/to/<app name>.app" \
  --output ~/Desktop/<app name>_debug_profile.trace \
  --time-limit 2m

Multiple Instruments

# Combine multiple instruments in one session
xcrun xctrace record \
  --device "iPhone 16 Pro Simulator (18.5)" \
  --instrument "Time Profiler" \
  --instrument "Allocations" \
  --instrument "Network" \
  --attach "<app name>" \
  --output ~/Desktop/<app name>_combined_analysis.trace \
  --time-limit 3m

Data Export and Analysis

Table of Contents Export

# View available data in trace file
xcrun xctrace export --input ~/Desktop/<app name>_launch_analysis.trace --toc

Specific Data Export

# Export CPU profiling data
xcrun xctrace export --input ~/Desktop/<app name>_cpu_profile.trace \
  --xpath '/trace-toc/run[@number="1"]/data/table[@schema="time-profiler"]' \
  --output ~/Desktop/cpu_data.xml

# Export memory allocation data
xcrun xctrace export --input ~/Desktop/<app name>_memory_analysis.trace \
  --xpath '/trace-toc/run[@number="1"]/data/table[@schema="allocations"]' \
  --output ~/Desktop/memory_data.xml

# Export network data as HAR file
xcrun xctrace export --input ~/Desktop/<app name>_network_analysis.trace \
  --har --output ~/Desktop/network_data.har

iOS Project Specific Workflows

Complete Performance Audit Script

#!/bin/bash
# <app name>_performance_audit.sh

# Configuration
DEVICE="iPhone 16 Pro Simulator (18.5)"
APP_PATH="/Users/daipham/Library/Developer/Xcode/DerivedData/<app name>-demupeapxadrllglwxuahiesemhe/Build/Products/Release-iphonesimulator/<app name>.app"
OUTPUT_DIR="~/Desktop/<app name>_performance_$(date +%Y%m%d_%H%M%S)"
BUNDLE_ID="<bundle id>"

# Create output directory
mkdir -p "$OUTPUT_DIR"

echo "🚀 Starting <app scheme> Performance Audit..."
echo "📁 Results will be saved to: $OUTPUT_DIR"

# 1. App Launch Analysis
echo "📱 Analyzing app launch performance..."
xcrun xctrace record --template "App Launch" \
  --device "$DEVICE" \
  --launch -- "$APP_PATH" \
  --output "$OUTPUT_DIR/launch_analysis.trace" \
  --time-limit 30s

# 2. Memory Allocations
echo "🧠 Analyzing memory allocations..."
xcrun xctrace record --template "Allocations" \
  --device "$DEVICE" \
  --attach "$BUNDLE_ID" \
  --output "$OUTPUT_DIR/memory_analysis.trace" \
  --time-limit 2m

# 3. CPU Profiling
echo "⚡ Profiling CPU usage..."
xcrun xctrace record --template "Time Profiler" \
  --device "$DEVICE" \
  --attach "$BUNDLE_ID" \
  --output "$OUTPUT_DIR/cpu_profile.trace" \
  --time-limit 2m

# 4. Memory Leaks
echo "🔍 Checking for memory leaks..."
xcrun xctrace record --template "Leaks" \
  --device "$DEVICE" \
  --attach "$BUNDLE_ID" \
  --output "$OUTPUT_DIR/leaks_analysis.trace" \
  --time-limit 3m

# 5. Network Activity
echo "🌐 Monitoring network activity..."
xcrun xctrace record --template "Network" \
  --device "$DEVICE" \
  --attach "$BUNDLE_ID" \
  --output "$OUTPUT_DIR/network_analysis.trace" \
  --time-limit 3m

# 6. Animation Performance
echo "🎬 Analyzing animation performance..."
xcrun xctrace record --template "Animation Hitches" \
  --device "$DEVICE" \
  --attach "$BUNDLE_ID" \
  --output "$OUTPUT_DIR/animation_analysis.trace" \
  --time-limit 2m

echo "✅ Performance audit complete!"
echo "📂 Open traces in Instruments.app for detailed analysis"
echo "🔗 Trace files location: $OUTPUT_DIR"

Continuous Integration Performance Testing

#!/bin/bash
# ci_performance_check.sh - For automated CI/CD pipelines

DEVICE="iPhone 16 Pro Simulator (18.5)"
APP_PATH="$1"  # Pass app path as parameter
THRESHOLD_LAUNCH_TIME=3.0  # seconds
THRESHOLD_MEMORY_MB=150    # MB

# Quick launch time check
echo "⏱️  Measuring app launch time..."
xcrun xctrace record --template "App Launch" \
  --device "$DEVICE" \
  --launch -- "$APP_PATH" \
  --output "launch_check.trace" \
  --time-limit 10s

# Extract launch time (simplified - would need proper parsing)
# LAUNCH_TIME=$(parse_launch_time launch_check.trace)

# Memory footprint check
echo "💾 Measuring memory footprint..."
xcrun xctrace record --template "Allocations" \
  --device "$DEVICE" \
  --launch -- "$APP_PATH" \
  --output "memory_check.trace" \
  --time-limit 30s

echo "📊 Performance check complete"
# Add logic to fail CI if thresholds exceeded

Development Workflow Integration

# Quick development profiling
alias <app name>_profile='xcrun xctrace record --template "Time Profiler" --device "iPhone 16 Pro Simulator (18.5)" --attach "<app name>" --output ~/Desktop/quick_profile_$(date +%H%M%S).trace --time-limit 1m'

alias <app name>_memory='xcrun xctrace record --template "Allocations" --device "iPhone 16 Pro Simulator (18.5)" --attach "<app name>" --output ~/Desktop/memory_check_$(date +%H%M%S).trace --time-limit 2m'

alias <app name>_launch='xcrun xctrace record --template "App Launch" --device "iPhone 16 Pro Simulator (18.5)" --launch -- "/Users/daipham/Library/Developer/Xcode/DerivedData/<app name>-demupeapxadrllglwxuahiesemhe/Build/Products/Release-iphonesimulator/<app name>.app" --output ~/Desktop/launch_$(date +%H%M%S).trace --time-limit 20s'

Tips and Best Practices

Device Selection

  • Use physical devices for accurate performance data
  • Simulators are good for development and debugging
  • Match device to your target audience (iPhone vs iPad)

Template Selection

  • App Launch: Essential for user experience optimization
  • Time Profiler: First choice for CPU performance issues
  • Allocations: Critical for memory management
  • Leaks: Important for long-term app stability
  • Network: Essential for apps with API calls (like )

Recording Duration

  • App Launch: 15-30 seconds
  • Memory Analysis: 2-5 minutes
  • CPU Profiling: 1-3 minutes
  • Leak Detection: 3-10 minutes (longer for thorough analysis)

Automation Best Practices

  • Always specify output paths to avoid conflicts
  • Use timestamp-based file naming
  • Set appropriate time limits to prevent infinite recording
  • Consider device state (clean vs. with existing apps)

Common XPath Expressions for Data Export

# CPU profiling data
--xpath '/trace-toc/run[@number="1"]/data/table[@schema="time-profiler"]'

# Memory allocations
--xpath '/trace-toc/run[@number="1"]/data/table[@schema="allocations"]'

# Network requests
--xpath '/trace-toc/run[@number="1"]/data/table[@schema="network-connections"]'

# App launch metrics
--xpath '/trace-toc/run[@number="1"]/data/table[@schema="app-launch"]'

# Animation hitches
--xpath '/trace-toc/run[@number="1"]/data/table[@schema="animation-hitches"]'

Troubleshooting

Common Issues and Solutions

1. "Provided device parameter is ambiguous"

Problem:

xcrun xctrace record --template "App Launch" --device "iPhone 17 Pro" ...
# Error: Provided device parameter 'iPhone 17 Pro' is ambiguous

Solution: Always use device UUID instead of name

# Get UUID first
xcrun simctl list devices available | grep "iPhone 17 Pro"
# Output: iPhone 17 Pro (F464E766-555C-4B95-B8CC-763702A70791) (Booted)

# Use UUID in command
xcrun xctrace record --template "App Launch" --device F464E766-555C-4B95-B8CC-763702A70791 ....

2. "Provided process is ambiguous"

Problem:

# Error: Provided process '/path/to/<app name>.app' is ambiguous
# /path1/<app name>.app
# /path2/<app name>.app

Root Cause: Multiple app installations exist on the simulator (common after repeated builds)

Solution: Clean up before profiling

# Method 1: Uninstall existing app
xcrun simctl uninstall $DEVICE_UUID <bundle id>

# Method 2: Erase entire simulator (nuclear option)
xcrun simctl shutdown $DEVICE_UUID
xcrun simctl erase $DEVICE_UUID
xcrun simctl boot $DEVICE_UUID

# Then reinstall fresh
xcrun simctl install $DEVICE_UUID /path/to/<app name>.app

3. "Export failed: Trace is malformed - run data is missing"

Problem:

xcrun xctrace export --input trace.trace --toc
# Error: Export failed: Trace is malformed - run data is missing

Root Cause: Trace file is still being written or profiling was interrupted

Solution:

  • Wait for profiling to fully complete (look for "Output file saved as:" message)
  • Don't try to export immediately after xctrace record completes
  • Some traces may not export properly via CLI - open in Instruments.app instead
# Check if profiling completed
ls -la *.trace  # Look for complete directory structure

# Open in Instruments for analysis instead
open -a Instruments.app trace.trace

4. "No such file or directory" with paths containing spaces

Problem:

xcrun xctrace record --input "/path with spaces/file.trace" ...
# Error: File does not exist at path

Solution: Use environment variables or proper quoting

# Method 1: Environment variable (RECOMMENDED)
TRACE_FILE="/path with spaces/file.trace"
xcrun xctrace export --input "$TRACE_FILE" --toc

# Method 2: Escape properly
xcrun xctrace export --input "/path\ with\ spaces/file.trace" --toc

5. Trace file saved in wrong location

Problem: Specified --output ~/Desktop/trace.trace but file appears in current directory

Root Cause: xctrace may ignore --output path and auto-generate filename

Solution:

# Trace files are saved with auto-generated names like:
# Launch_<app name>.app_2025-10-30_3.55.40 PM_39E6A410.trace

# Find your trace file
find . -name "*.trace" -type d -mmin -5  # Files modified in last 5 minutes

# Or look for specific pattern
ls -lt *.trace | head -1  # Most recent trace

6. App Launch template not capturing data

Problem: Trace file created but no meaningful data

Solution:

  • Ensure app actually launches (check simulator)
  • Build app in Release configuration for realistic performance
  • Don't specify --time-limit too short (use at least 10-15 seconds)
  • Check that device is booted before profiling
# Verify device is booted
xcrun simctl list devices | grep Booted

# Boot if needed
xcrun simctl boot $DEVICE_UUID

Debugging Commands

# List all available devices with UUIDs
xcrun simctl list devices available

# Check if app is installed
xcrun simctl listapps $DEVICE_UUID | grep <app name>

# Verbose output
xcrun xctrace record --template "Time Profiler" --device "$DEVICE_UUID" --time-limit 30s --verbose

# Check available instruments
xcrun xctrace list instruments

# Validate trace file structure
ls -la trace.trace/

# Open trace in Instruments GUI (most reliable for analysis)
open -a Instruments.app trace.trace

Best Practices to Avoid Issues

  1. Always use device UUID - Never use device names
  2. Clean state before profiling - Uninstall app or erase simulator first
  3. Use environment variables - For paths with spaces or complex names
  4. Wait between steps - Add sleep 2 after installation before profiling
  5. Build in Release mode - For accurate performance measurements
  6. Check output location - Trace files may have auto-generated names
  7. Use Instruments.app - For final analysis when CLI export fails

Lessons Learned from Real-World Usage (2025-10-30)

What Worked

  1. Device UUID approach: Using xcrun simctl list devices available | grep "iPhone" to get UUID, then using UUID in all commands
  2. Clean installation: Running xcrun simctl uninstall before each profiling session eliminated ambiguity errors
  3. Environment variables: Using DEVICE_UUID="..." made commands more reliable with special characters
  4. Background execution: Using 2>&1 redirect and run_in_background for long-running profiles
  5. Auto-generated filenames: Accepting that xctrace generates its own filenames (e.g., Launch_<app name>.app_2025-10-30_3.55.40 PM_39E6A410.trace)

What Didn't Work

  1. Device names: --device "iPhone 17 Pro" or --device "iPhone 16 Pro Simulator (18.5)" - Always ambiguous
  2. Direct export: xcrun xctrace export --input trace.trace --toc often failed with "malformed trace" errors
  3. Absolute --output paths: Often ignored by xctrace, files saved with auto-generated names instead
  4. Multiple app installations: Caused "process is ambiguous" errors - must clean up first
  5. Immediate export: Trying to export trace immediately after recording before file fully written

Performance Improvements Achieved

From this profiling session, we identified and fixed these launch time issues in app:

  1. Lazy ViewModel initialization: Deferred 7 use case resolutions from eager to lazy loading
  2. Deferred swizzling: Moved 4 tracking swizzle operations to background thread
  3. Background font loading: Moved FontFamily.registerAllCustomFonts() off main thread
  4. Deferred RxSwift bindings: Moved subscription setup to next run loop iteration

Expected improvement: 40-60% reduction in main thread blocking during launch

#!/bin/bash
# Proven workflow for app launch profiling

# 1. Setup
DEVICE_UUID="F464E766-555C-4B95-B8CC-763702A70791"
APP_PATH="/Users/<username>/Library/Developer/Xcode/DerivedData/<app name>/Build/Products/Release-iphonesimulator/<app name>.app"

# 2. Build in Release
xcodebuild -workspace <app name>.xcworkspace \
  -scheme "<app scheme>" \
  -configuration Release \
  -sdk iphonesimulator \
  -derivedDataPath ~/Library/Developer/Xcode/DerivedData/<app name> \
  build

# 3. Clean simulator state
xcrun simctl uninstall $DEVICE_UUID <bundle id>

# 4. Install fresh
xcrun simctl install $DEVICE_UUID "$APP_PATH"
sleep 2

# 5. Profile
xcrun xctrace record --template "App Launch" \
  --device $DEVICE_UUID \
  --launch -- "$APP_PATH" 2>&1

# 6. Find and open trace
TRACE=$(ls -t Launch_<app name>*.trace 2>/dev/null | head -1)
echo "Trace saved to: $TRACE"
open -a Instruments.app "$TRACE"

This workflow has been tested and verified to work reliably.