A native macOS app that provides a graphical interface for Apple's xcrun simctl,
making iOS Simulator management and debugging effortless.
- 🖥️ Boot, shutdown, rename, clone, erase, and delete simulators
- 📋 Create new simulators with runtime and device type pickers
- 🔍 Browse simulators grouped by runtime, with booted simulators pinned at the top
- 📎 Copy UDID, reveal in Finder, and more via context menu
- 📱 View all installed apps with extracted icons in a grid
- 📦 Install
.appbundles, uninstall, launch, and terminate apps - 🚀 Launch apps with custom arguments and environment variables
- ℹ️ Inspect full
Info.plist, URL schemes, and save app icons - 🔐 Grant, revoke, or reset privacy permissions per app
- 📂 Navigate the simulator file system with breadcrumb navigation
- ⚡ Quick-jump to Root, Photos, and Downloads directories
- 👁️ Preview images, video, text, plist, and JSON files
- 📥 Import files from Mac, export, delete, and copy paths
- 🖼️ Browse photos and videos from the simulator's DCIM directory
- ➕ Import media via drag-and-drop or file picker
- 🗑️ Delete media with automatic SQLite Photos database cleanup
▶️ Full video playback with Quick Look preview
- 📸 Screenshots in PNG, JPEG, TIFF, BMP, or GIF
- 🎥 Screen recording with H.264 or HEVC codec
- 🎭 Mask policies: ignored, alpha, or black
- 💾 Configurable save directory
- 🗺️ Interactive MapKit map with pin placement
- 📍 12 built-in city presets (Apple Park, San Francisco, New York, London, Tokyo, Shanghai, Beijing, and more)
- ⭐ Save and manage custom location presets
- 🎯 Set or clear simulated GPS coordinates
- 🔔 Compose push notifications with a full APNs JSON payload editor
- 📝 JSON formatting and template reset
- 📂 Import
.apnsfiles - 📱 App picker for target selection
- 📡 Real-time log streaming via
log stream - 🔍 Filter by level, process, subsystem, and text search
- 📊 Configurable buffer size (up to 10,000 entries)
- 📋 Copy messages, JSON detail view, and auto-scroll
- 📋 Pasteboard — Copy text to and paste from the simulator clipboard
- 🔑 Keychain — Import root certificates, import certificates, and reset the keychain
- 🌐 Environment Variables — Read simulator env vars with quick-access buttons
- 💻 Process Spawn — Execute arbitrary commands on the simulator
- 🌗 Toggle Light/Dark mode on the simulator
- 📏 Override Dynamic Type content size
- 📊 Override status bar: time, network type, battery level, Wi-Fi/cellular bars, operator name
| Shortcut | Action |
|---|---|
⌘ B |
Boot selected simulator |
⇧⌘ S |
Shutdown selected simulator |
⌘ R |
Refresh simulator list |
Space |
Preview file in file browser |
- 🇺🇸 English
- 🇨🇳 Simplified Chinese
- macOS 14.0+ (Sonoma or later)
- Xcode 15.0+
- Swift 5.9+
- iOS Simulator (installed with Xcode)
# Clone the repository
git clone https://github.com/ownlight6/SimDebug.git
cd SimDebug
# Build with Swift Package Manager
swift build
# Or build in release mode
swift build -c release
# Or open in Xcode
open SimDebug.xcodeprojNote: The Xcode project is generated from
project.ymlvia XcodeGen. If you add new files, regenerate the project withxcodegenor add them directly through Xcode.
SimDebug follows MVVM with actor-based services:
Views (SwiftUI) → ViewModels (@MainActor) → Services (actor/class) → xcrun simctl
| Layer | Directory | Responsibility |
|---|---|---|
| Views | SimDebug/Views/ |
SwiftUI views — never call simctl directly |
| ViewModels | SimDebug/ViewModels/ |
@MainActor ObservableObject classes with @Published properties |
| Models | SimDebug/Models/ |
Plain structs: SimulatorDevice, InstalledApp, FileNode, etc. |
| Services | SimDebug/Services/ |
Singleton actors/classes wrapping simctl via Process |
| Utilities | SimDebug/Utilities/ |
Icon extraction, plist parsing, constants |
Key services:
| Service | Type | Description |
|---|---|---|
SimctlService.shared |
actor |
Central simctl command wrapper |
ProcessRunner.shared |
actor |
Async Process execution and output streaming |
FileSystemManager.shared |
class |
FileManager-based simulator file access |
LocationService.shared |
actor |
GPS location simulation |
ScreenshotService |
class |
Screenshot and screen recording |
Global state: AppState and SimulatorListViewModel are injected as .environmentObject() at the root. AppState.simulatorBootedCounter signals content views to refresh after boot.
SimDebug/
├── App/
│ ├── AppState.swift # Global state, ContentTab enum
│ └── SimDebugApp.swift # @main entry point, settings, menu commands
├── Models/
│ ├── FileNode.swift # File system tree node
│ ├── InstalledApp.swift # Installed app model + JSON parsing
│ ├── LocationCoordinate.swift # Coordinate model + built-in presets
│ ├── LogEntry.swift # Log entry model + parsers
│ ├── PushNotification.swift # APNs payload model
│ └── SimulatorDevice.swift # Simulator, device type, runtime models
├── ViewModels/
│ ├── AppearanceViewModel.swift # Appearance, status bar, privacy
│ ├── AppListViewModel.swift # App listing, install/uninstall/launch
│ ├── FileBrowserViewModel.swift # File system navigation
│ ├── LocationViewModel.swift # GPS simulation + custom presets
│ ├── LogsViewModel.swift # Real-time log streaming + filtering
│ ├── PushNotificationViewModel.swift
│ ├── ScreenshotViewModel.swift # Screenshot + screen recording
│ ├── SimulatorListViewModel.swift # Sidebar: list, boot, create, clone…
│ └── ToolsViewModel.swift # Pasteboard, keychain, env vars, spawn
├── Views/
│ ├── Apps/ # App grid, detail, info sheet, launch options
│ ├── Appearance/ # Light/Dark, content size, status bar override
│ ├── Files/ # File browser, preview
│ ├── Location/ # Map + coordinate input + presets
│ ├── Logs/ # Real-time log stream viewer
│ ├── Main/ # NavigationSplitView, empty state
│ ├── Media/ # Photo/video grid, import, delete
│ ├── Push/ # Push notification composer
│ ├── Shared/ # AsyncButton, SearchField
│ ├── Shortcuts/ # Screenshot, recording, open URL
│ ├── Sidebar/ # Simulator list, context menu, create sheet
│ └── Tools/ # Pasteboard, keychain, env vars, process spawn
├── Services/
│ ├── FileSystemManager.swift # FileManager-based file operations
│ ├── LocationService.swift # GPS simulation
│ ├── ProcessRunner.swift # Async Process execution + streaming
│ ├── ScreenshotService.swift # Screenshot/recording orchestration
│ └── SimctlService.swift # Central simctl command wrapper
├── Utilities/
│ ├── Constants.swift # App-wide constants
│ ├── IconExtractor.swift # App icon extraction from .app bundles
│ └── PlistParser.swift # Plist-to-JSON, Info.plist metadata parser
└── Resources/
├── Assets.xcassets/ # App icon
├── en.lproj/ # English localization
└── zh-Hans.lproj/ # Simplified Chinese localization
Contributions are welcome! Please feel free to submit a Pull Request.
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
This project is licensed under the MIT License — see the LICENSE file for details.