Xcode Simulatorは、物理デバイスなしでMac上でiOSアプリケーションを実行するAppleの組み込みツールです。シミュレータはホストのx86_64アーキテクチャ用にコードをコンパイルするため、高いテスト速度を実現します。Appleドキュメントでは、iPhone、iPad、Apple Watch、Apple TV向けシミュレータを使用した完全なデバッグサイクルについて説明しています。
重要ポイント
Xcode Simulatorは、Mac上で直接iOSアプリケーションを実行およびデバッグするためのツールです。Androidエミュレータとは異なり、AppleのシミュレータはデバイスのARMプロセッサをエミュレートしません。代わりに、コードはホストアーキテクチャ(Intel Macではx86_64、Apple Siliconではarm64)のマシンコードにコンパイルされます。
シミュレータはSDKから直接iOSフレームワークを使用し、UIKit、SwiftUI、Foundation、Core Dataへのアクセスを提供します。Apple(WWDC 2024)によると、90%以上の開発者が開発段階でシミュレータを使用し、最終テストのためだけに物理デバイスを接続しています。
Xcodeの各バージョンには、さまざまなデバイスモデルとiOSバージョン用のシミュレータセットが含まれています。例えば、Xcode 16にはiOS 18を搭載したiPhone 16 Pro、iPadOS 18を搭載したiPad Pro M4、Apple Watch Series 10、Apple TV 4Kのシミュレータが含まれています。
シミュレータはMac App StoreからXcodeと一緒にインストールされます。追加のiOSバージョンを追加するには、メニューSettings → Platformsを使用します。ビルドスキームでシミュレータを選択し、Runを押します。あるいは、Xcode → Open Developer Tool → Simulatorメニューからシミュレータを起動します。
// シミュレータの最小iOSバージョンの確認
if #available(iOS 18.0, *) {
print("iOS 18 API利用可能")
}シミュレータと実デバイスの違いを理解することは、品質テストにおいて極めて重要です。主な違いは、プロセッサアーキテクチャ、ハードウェア機能、グラフィックスパフォーマンスにあります。
| 特性 | シミュレータ | 実デバイス |
|---|---|---|
| CPUアーキテクチャ | x86_64 / arm64(Mac) | ARM64(Apple Silicon) |
| GPU Metal | Mac GPU経由のシミュレーション | ネイティブApple GPU |
| カメラ | 利用不可 | フル機能 |
| 加速度計/ジャイロスコープ | 利用不可 | ハードウェアセンサー |
| Touch ID / Face ID | メニュー経由のシミュレーション | ハードウェア生体認証 |
| プッシュ通知 | Xcode 11.4以降(.apnsファイル) | APNsサーバー |
| Bluetooth LE | 非対応 | フルスタック |
シミュレータのパフォーマンスは通常、実デバイスよりも高くなります。これはMacの強力なプロセッサを使用するためです。これにより、速度に関して誤った印象を与える可能性があります。アニメーション、Core Data操作、ネットワークリクエストは実デバイスではより遅く動作する可能性があります。
リリース前には必ず実デバイスでアプリケーションを実行してください。重要なシナリオ:カメラとAVFoundation、BluetoothとCoreBluetooth、APNs経由のプッシュ通知、App Sandboxでのファイルシステム操作、Metalでのグラフィックスパフォーマンス、バッテリー消費。
シミュレータ用のコードの条件付きコンパイルのために、AppleはObjective-CでTARGET_OS_SIMULATOR、SwiftでtargetEnvironment(simulator)を提供しています。このチェックにより、デバッグログの追加、モックオブジェクトの使用、ハードウェア依存コードの無効化が可能になります。
import UIKit
class CameraViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
#if targetEnvironment(simulator)
showMockCameraPreview()
print("シミュレータ:モックカメラの使用")
#else
setupRealCameraSession()
#endif
}
}Objective-Cでは、#if TARGET_OS_SIMULATORディレクティブも同様に機能します。ハードウェアセンサーやカメラを必要とするコードを無効にするために使用します。シミュレータ用のコンパイル時には、このコードはバイナリファイルに含まれません。
#if TARGET_OS_SIMULATOR
NSLog(@"シミュレータで実行中 — カメラ利用不可");
self.cameraButton.hidden = YES;
#else
self.cameraButton.hidden = NO;
#endifTARGET_OS_SIMULATORチェックは3つのケースで使用されます:UIテスト中のカメラをモックオブジェクトで置き換える、開発を高速化するためにCore Bluetoothを無効にする、リリースビルドに含めるべきでないデバッグ情報をログ出力する。ビジネスロジックを変更するためにチェックを使用することは避けてください — 実デバイスでバグを引き起こす可能性があります。
Xcode Simulatorは完全なXCTestテストスイートをサポートしています:単体テスト(XCTestCase)、UIテスト(XCUITestCase)、パフォーマンステスト。シミュレータでのテストには署名済みの開発者証明書は不要で、CI/CDの設定を簡素化します。
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)
}
}コマンドラインからテストを実行するには、スキームとシミュレータを指定してxcodebuild testを使用します。-destinationパラメータは、テストを実行する特定のシミュレータを定義します。
# iPhone 16シミュレータ、iOS 18で単体テストを実行
xcodebuild test \
-scheme "MyApp" \
-destination "platform=iOS Simulator,name=iPhone 16,OS=18.0" \
-testPlan "AllTests"便利さにもかかわらず、Xcode Simulatorには実デバイスでバグを引き起こす可能性のあるいくつかの制限があります。最も重要なのはARMエミュレーションの欠如です:コードはホストアーキテクチャ用にコンパイルされ、一部の操作の動作が異なる場合があります。
Core Dataとファイルシステムは、MacのSSDによりシミュレータ上でより高速に動作します。NANDメモリを搭載した実デバイスでは、読み取り/書き込み速度が低下します。リリース前には、特に大規模なデータセットの場合、デバイスでCore Dataのパフォーマンスをテストしてください。
シミュレータでの消費電力の確認は不可能です — シミュレータはMacから給電されます。コンテンツのロードやフェッチ操作を含むバックグラウンドモードは、バッテリーの制限とBackground Task Schedulerにより、実デバイスでは異なる動作をします。
シミュレータはiPhoneのハードウェアセンサーにアクセスできません。Face IDとTouch IDはシミュレータメニューからシミュレートできます:Features → Face ID → Matching Face。加速度計、ジャイロスコープ、気圧計は利用できません — CMDeviceMotionに依存するコードはデバイスでテストする必要があります。Core Locationについては、GPXファイルを選択してDebug → Simulate Locationから座標を設定できます。
シミュレータでのiCloudとStoreKitの確認も制限されています。StoreKit Testを使用すると、実際のApp Store Connectなしで購入をシミュレートできますが、Sandbox環境と本番購入の確認には物理デバイスが必要です。シミュレータでのiCloud DriveとCloudKitの同期は正しく機能しません — Appleはこれらのシナリオを実際のデバイスでのみテストすることを推奨しています。
Mシリーズプロセッサを搭載したMacでは、シミュレータは根本的に異なる動作をします:コードはx86_64ではなくネイティブARM64にコンパイルされます(実際のiPhoneと同様)。これにより、シミュレータとデバイスのギャップが大幅に縮小されます。Apple Siliconシミュレータで実行されるアプリケーションは、物理的なiPhoneと同じARM命令を使用するため、パフォーマンステストの代表性が高まります。Mシリーズシミュレータと実際のiPhoneの間のMetalおよびCore Animationのパフォーマンスの差は、Intelシミュレータと比較して最小限です。
CI向けシミュレータの設定には、必要なデバイスとiOSバージョンを事前に作成する必要があります。継続的インテグレーションサーバーでは、シミュレータは自動的に作成されません — テスト実行前にxcrun simctl createを使用して追加する必要があります。
# CI用シミュレータの作成
xcrun simctl create \
"iPhone 16 CI" \
"com.apple.CoreSimulator.SimDeviceType.iPhone-16" \
"com.apple.CoreSimulator.SimRuntime.iOS-18-0"
# 作成したシミュレータでテストを実行
xcodebuild test \
-workspace MyApp.xcworkspace \
-scheme MyApp \
-destination "id=$(xcrun simctl list devices | grep 'iPhone 16 CI' | awk -F'[][]' '{print }')"CIでの並列テストのために、異なるiOSバージョンを持つ複数のシミュレータを設定します。Xcode Cloud、GitHub Actions、Bitriseは並列テスト実行をサポートしており、実行時間を2〜3倍短縮します。CIサーバーにテストに必要なすべてのiOSシミュレータがインストールされていることを確認してください。
よくある質問
シミュレータはx86_64アーキテクチャで動作しMacのCPUを使用しますが、実デバイスはARM64 Apple Siliconで動作します。シミュレータはカメラ、センサー、GPU Metal、Bluetooth LE、バッテリーをエミュレートしません。コードはホストアーキテクチャ用にコンパイルされるため、シミュレータでのパフォーマンステストは代表的ではありません。
Swiftでは#if targetEnvironment(simulator)、Objective-Cでは#if TARGET_OS_SIMULATORを使用します。これらは条件付きコンパイルディレクティブです:ブロック内のコードはシミュレータ上でのみ実行されます。実デバイスでは利用できないカメラのモックオブジェクトやデバッグログに便利です。
はい、Xcode 11.4以降、シミュレータはJSON構造の.apnsファイルによるプッシュ通知のシミュレーションをサポートしています。ファイルを実行中のシミュレータにドラッグするか、xcrun simctl pushコマンドを使用します。通知は実デバイスと同様に完全に表示されます。
シミュレータはカメラ、マイク、加速度計、ジャイロスコープ、TrueDepth、Touch ID(シミュレーションを除く)、Face ID(シミュレーションを除く)、Bluetooth LE、NFCをサポートしていません。MetalのパフォーマンスはMac GPUでシミュレートされ、実際のiPhoneのパフォーマンスを反映しません。消費電力は測定できません。
xcrun simctl createでシミュレータを作成し、platform=iOS Simulatorとデバイス名を指定した-destinationパラメータ付きでxcodebuild testを実行します。並列テストの場合は、CI設定で異なるiOSバージョンの複数のシミュレータを作成します。
まとめ
ターンキー方式のモバイルアプリケーションを開発します
IT Sectrは2017年からスタートアップや企業向けにiOS・Androidアプリケーションを開発しています。私たちがご相談に乗り、最適なソリューションをご提案します。