iOS Simulator: What It Is and How It Works in Xcode

Author: IT Sectr Published: 2026-02-09 Reading time: 8 min

Xcode Simulator is a built-in Apple tool that runs iOS applications on a Mac without a physical device. The simulator compiles code for the host's x86_64 architecture, providing high testing speed. Apple Documentation describes the full debugging cycle using the simulator for iPhone, iPad, Apple Watch and Apple TV.

Key Takeaways

  • Xcode Simulator — emulation of iOS device at the application level without full ARM architecture emulation
  • Difference from real device — the simulator does not support camera, GPU Metal, sensors and push notifications (before Xcode 11.4)
  • TARGET_OS_SIMULATOR — a directive for checking the runtime environment in Objective-C and Swift code
  • Unit tests and UI tests — the simulator supports the full XCTest suite with the ability to run on CI servers
  • Multiple platforms — the simulator supports iPhone, iPad, Apple Watch, Apple TV and Vision Pro

What is Simulator in Xcode?

Xcode Simulator is a tool for running and debugging iOS applications directly on a Mac. Unlike the Android emulator, Apple's simulator does not emulate the device's ARM processor. Instead, the code is compiled into the machine code of the host architecture (x86_64 on Intel Mac or arm64 on Apple Silicon).

The simulator uses iOS frameworks directly from the SDK, providing access to UIKit, SwiftUI, Foundation and Core Data. According to Apple (WWDC 2024), over 90% of developers use the simulator during the development stage, connecting physical devices only for final testing.

Each version of Xcode includes a set of simulators for different device models and iOS versions. For example, Xcode 16 includes simulators for iPhone 16 Pro with iOS 18, iPad Pro M4 with iPadOS 18, Apple Watch Series 10 and Apple TV 4K.

Installing and launching the simulator

The simulator is installed together with Xcode from the Mac App Store. To add additional iOS versions use the menu Settings → Platforms. Select a simulator in the build scheme and press Run. Alternatively, launch the simulator via the menu Xcode → Open Developer Tool → Simulator.

swift
// Checking minimum iOS version for simulator
if #available(iOS 18.0, *) {
    print("iOS 18 APIs available")
}

Differences between simulator and real device

Understanding the differences between the simulator and a real device is critically important for quality testing. The main differences lie in processor architecture, hardware capabilities and graphics performance.

CharacteristicSimulatorReal device
CPU Architecturex86_64 / arm64 (Mac)ARM64 (Apple Silicon)
GPU MetalSimulation via Mac GPUNative Apple GPU
CameraUnavailableFull-featured
Accelerometer/GyroscopeUnavailableHardware sensors
Touch ID / Face IDSimulation via menuHardware biometrics
Push notificationsSince Xcode 11.4 (.apns file)APNs server
Bluetooth LENot supportedFull stack

Performance in the simulator is usually higher than on a real device because it uses the Mac's powerful processor. This creates a false impression of speed. Animations, Core Data operations and network requests on a real device may run slower.

When you must test on a device

Be sure to run the application on a real device before release. Critical scenarios: camera and AVFoundation, Bluetooth and CoreBluetooth, push notifications via APNs, file system operations in App Sandbox, graphics performance in Metal, and battery power consumption.

Checking TARGET_OS_SIMULATOR in code

For conditional compilation of code for the simulator, Apple provides TARGET_OS_SIMULATOR in Objective-C and targetEnvironment(simulator) in Swift. This check allows you to add debug logs, mock objects or disable hardware-dependent code.

swift
import UIKit

class CameraViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        
        #if targetEnvironment(simulator)
        showMockCameraPreview()
        print("Simulator: using mock camera")
        #else
        setupRealCameraSession()
        #endif
    }
}

In Objective-C the #if TARGET_OS_SIMULATOR directive works similarly. Use it to disable code that requires hardware sensors or a camera. At compile time for the simulator, this code does not end up in the binary file.

objective-c
#if TARGET_OS_SIMULATOR
NSLog(@"Running in simulator — camera unavailable");
self.cameraButton.hidden = YES;
#else
self.cameraButton.hidden = NO;
#endif

Typical use cases for the check

The TARGET_OS_SIMULATOR check is used in three cases: replacing the camera with a mock object during UI tests, disabling Core Bluetooth to speed up development, and logging debug information that should not end up in the release build. Avoid using the check to change business logic — this can lead to bugs on a real device.

Running tests in the simulator

Xcode Simulator supports the full XCTest test suite: Unit tests (XCTestCase), UI tests (XCUITestCase) and performance tests. Testing on the simulator does not require a signed developer certificate, which simplifies CI/CD setup.

swift
import XCTest

final class LoginTests: XCTestCase {
    var app: XCUIApplication!
    
    override func setUp() {
        continueAfterFailure = false
        app = XCUIApplication()
        app.launch()
    }
    
    func testLoginButtonExists() {
        XCTAssertTrue(app.buttons["loginButton"].exists)
    }
    
    func testEmptyEmailValidation() {
        app.textFields["emailField"].tap()
        app.buttons["loginButton"].tap()
        let errorLabel = app.staticTexts["errorMessage"]
        XCTAssertTrue(errorLabel.exists)
    }
}

To run tests from the command line use xcodebuild test with the scheme and simulator specified. The -destination parameter defines the specific simulator on which the tests will be run.

bash
# Running Unit Tests on iPhone 16 Simulator, iOS 18
xcodebuild test \
  -scheme "MyApp" \
  -destination "platform=iOS Simulator,name=iPhone 16,OS=18.0" \
  -testPlan "AllTests"

Limitations and pitfalls

Despite its convenience, Xcode Simulator has a number of limitations that can lead to bugs on a real device. The most critical is the lack of ARM emulation: the code is compiled for the host architecture, and the behavior of some operations may differ.

Core Data and file system work faster on the simulator due to the Mac's SSD. On a real device with NAND memory, read/write speed is lower. Test Core Data performance on a device before release, especially for large data sets.

Checking power consumption on the simulator is impossible — the simulator is powered by the Mac. Background modes, including content loading and fetch operations, behave differently on a real device due to battery limitations and the Background Task Scheduler.

Hardware sensors and biometrics

The simulator does not have access to the iPhone's hardware sensors. Face ID and Touch ID can be simulated via the simulator menu: Features → Face ID → Matching Face. Accelerometer, gyroscope and barometer are unavailable — code relying on CMDeviceMotion needs to be tested on a device. For Core Location you can set coordinates via Debug → Simulate Location by selecting a GPX file.

Checking iCloud and StoreKit on the simulator is also limited. StoreKit Test allows you to simulate purchases without a real App Store Connect, but checking the Sandbox environment and production purchases requires a physical device. iCloud Drive and CloudKit synchronization on the simulator works incorrectly — Apple recommends testing these scenarios only on real devices.

Simulator on Apple Silicon Mac

On Macs with M-series processors, the simulator works fundamentally differently: the code is compiled into native ARM64, as on a real iPhone, rather than x86_64. This significantly narrows the gap between the simulator and the device. Applications running on the Apple Silicon simulator use the same ARM instructions as on a physical iPhone, making performance tests more representative. The difference in Metal and Core Animation performance between the M-series simulator and a real iPhone is minimal compared to the Intel simulator.

Configuring simulator for CI

Setting up a simulator for CI requires pre-creating the required device and iOS version. On Continuous Integration servers, simulators are not created automatically — they need to be added via xcrun simctl create before running tests.

bash
# Creating simulator for CI
xcrun simctl create \
  "iPhone 16 CI" \
  "com.apple.CoreSimulator.SimDeviceType.iPhone-16" \
  "com.apple.CoreSimulator.SimRuntime.iOS-18-0"

# Running tests on the created simulator
xcodebuild test \
  -workspace MyApp.xcworkspace \
  -scheme MyApp \
  -destination "id=$(xcrun simctl list devices | grep 'iPhone 16 CI' | awk -F'[][]' '{print }')"

For parallel testing on CI, configure several simulators with different iOS versions. Xcode Cloud, GitHub Actions and Bitrise support parallel test execution, reducing run time by 2-3 times. Make sure all required iOS simulators for testing are installed on the CI server.

Frequently Asked Questions

How is Xcode Simulator different from a real device?

The simulator runs on x86_64 architecture and uses the Mac CPU, while a real device runs on ARM64 Apple Silicon. The simulator does not emulate the camera, sensors, GPU Metal, Bluetooth LE or battery. The code is compiled for the host architecture, so performance tests on the simulator are not representative.

How do I check in code whether the app is running on the simulator?

Use #if targetEnvironment(simulator) in Swift or #if TARGET_OS_SIMULATOR in Objective-C. These are conditional compilation directives: the code in the block executes only on the simulator. Useful for mock camera objects and debug logs that are unavailable on a real device.

Can I test push notifications on the simulator?

Yes, starting with Xcode 11.4 the simulator supports simulating push notifications via an .apns file with a JSON structure. Drag the file onto the running simulator or use the xcrun simctl push command. Notifications appear fully just like on a real device.

What are the limitations of Xcode Simulator?

The simulator does not support camera, microphone, accelerometer, gyroscope, TrueDepth, Touch ID (except simulation), Face ID (except simulation), Bluetooth LE and NFC. Metal performance is simulated on the Mac GPU, which does not reflect real iPhone performance. Power consumption cannot be measured.

How to run tests on CI using the simulator?

Create a simulator via xcrun simctl create, then run xcodebuild test with the -destination parameter specifying platform=iOS Simulator and the device name. For parallel testing, create several simulators with different iOS versions in the CI configuration.

Summary

  • Xcode Simulator — a tool for running iOS applications on a Mac, compiling code for the host architecture without ARM emulation
  • Differences from device — the simulator does not support camera, GPU Metal, sensors, Bluetooth, NFC and does not provide representative performance
  • Conditional compilation — TARGET_OS_SIMULATOR and targetEnvironment(simulator) allow adding mock objects and debug logs
  • Testing — XCTest supports Unit, UI and performance tests on the simulator without a developer certificate
  • CI setup — create simulators via xcrun simctl and run parallel tests on multiple iOS versions
  • Critical scenarios — camera, Bluetooth, push notifications and Metal performance require testing on a real device
  • Apple Silicon Mac — the simulator on M-series runs iOS applications with minimal architectural differences

We will develop a mobile application turnkey

IT Sectr creates iOS and Android applications for startups and businesses since 2017. We will advise you and propose the best solution.

Discuss the project

Read also