[ios] How can I programmatically determine if my app is running in the iphone simulator?

As the question states, I would mainly like to know whether or not my code is running in the simulator, but would also be interested in knowing the specific iphone version that is running or being simulated.

EDIT: I added the word 'programmatically' to the question name. The point of my question is to be able to dynamically include / exclude code depending on which version / simulator is running, so I'd really be looking for something like a pre-processor directive that can provide me this info.

This question is related to ios objective-c swift xcode ios-simulator

The answer is


In swift :

#if (arch(i386) || arch(x86_64))
...            
#endif

From Detect if app is being built for device or simulator in Swift


Updated code:

This is purported to work officially.

#if TARGET_IPHONE_SIMULATOR
NSString *hello = @"Hello, iPhone simulator!";
#elif TARGET_OS_IPHONE
NSString *hello = @"Hello, device!";
#else
NSString *hello = @"Hello, unknown target!";
#endif

Original post (since deprecated)

This code will tell you if you are running in a simulator.

#ifdef __i386__
NSLog(@"Running in the simulator");
#else
NSLog(@"Running on a device");
#endif

To include all types of "simulators"

NSString *model = [[UIDevice currentDevice] model];
if([model rangeOfString:@"Simulator" options:NSCaseInsensitiveSearch].location !=NSNotFound)
{
    // we are running in a simulator
}

I had the same problem, both TARGET_IPHONE_SIMULATOR and TARGET_OS_IPHONE are always defined, and are set to 1. Pete's solution works, of course, but if you ever happen to build on something other than intel (unlikely, but who knows), here's something that's safe as long as the iphone hardware doesn't change (so your code will always work for the iphones currently out there):

#if defined __arm__ || defined __thumb__
#undef TARGET_IPHONE_SIMULATOR
#define TARGET_OS_IPHONE
#else
#define TARGET_IPHONE_SIMULATOR 1
#undef TARGET_OS_IPHONE
#endif

Put that somewhere convenient, and then pretend that the TARGET_* constants were defined correctly.


Apple has added support for checking the app is targeted for the simulator with the following:

#if targetEnvironment(simulator)
let DEVICE_IS_SIMULATOR = true
#else
let DEVICE_IS_SIMULATOR = false
#endif

/// Returns true if its simulator and not a device

public static var isSimulator: Bool {
    #if (arch(i386) || arch(x86_64)) && os(iOS)
        return true
    #else
        return false
    #endif
}

THERE IS A BETTER WAY NOW!

As of Xcode 9.3 beta 4 you can use #if targetEnvironment(simulator) to check.

#if targetEnvironment(simulator)
//Your simulator code
#endif

UPDATE
Xcode 10 and iOS 12 SDK supports this too.


Has anyone considered the answer provided here?

I suppose the objective-c equivalent would be

+ (BOOL)isSimulator {
    NSOperatingSystemVersion ios9 = {9, 0, 0};
    NSProcessInfo *processInfo = [NSProcessInfo processInfo];
    if ([processInfo isOperatingSystemAtLeastVersion:ios9]) {
        NSDictionary<NSString *, NSString *> *environment = [processInfo environment];
        NSString *simulator = [environment objectForKey:@"SIMULATOR_DEVICE_NAME"];
        return simulator != nil;
    } else {
        UIDevice *currentDevice = [UIDevice currentDevice];
        return ([currentDevice.model rangeOfString:@"Simulator"].location != NSNotFound);
    }
}

My answer is based on @Daniel Magnusson answer and comments of @Nuthatch and @n.Drake. and I write it to save some time for swift users working on iOS9 and onwards.

This is what worked for me:

if UIDevice.currentDevice().name.hasSuffix("Simulator"){
    //Code executing on Simulator
} else{
    //Code executing on Device
}

In my opinion, the answer (presented above and repeated below):

NSString *model = [[UIDevice currentDevice] model];
if ([model isEqualToString:@"iPhone Simulator"]) {
    //device is simulator
}

is the best answer because it is obviously executed at RUNTIME versus being a COMPILE DIRECTIVE.


Not pre-processor directive, but this was what I was looking for when i came to this question;

NSString *model = [[UIDevice currentDevice] model];
if ([model isEqualToString:@"iPhone Simulator"]) {
    //device is simulator
}

Not pre-processor directive, but this was what I was looking for when i came to this question;

NSString *model = [[UIDevice currentDevice] model];
if ([model isEqualToString:@"iPhone Simulator"]) {
    //device is simulator
}

With Swift 4.2 (Xcode 10), we can do this

#if targetEnvironment(simulator)
  //simulator code
#else 
  #warning("Not compiling for simulator")
#endif

For Swift 4.2 / xCode 10

I created an extension on UIDevice, so I can easily ask for if the simulator is running.

// UIDevice+CheckSimulator.swift

import UIKit

extension UIDevice {

    /// Checks if the current device that runs the app is xCode's simulator
    static func isSimulator() -> Bool {        
        #if targetEnvironment(simulator)
            return true
        #else
            return false
        #endif
    }
}

In my AppDelegate for example I use this method to decide wether registering for remote notification is necessary, which is not possible for the simulator.

// CHECK FOR REAL DEVICE / OR SIMULATOR
if UIDevice.isSimulator() == false {

    // REGISTER FOR SILENT REMOTE NOTIFICATION
    application.registerForRemoteNotifications()
}

With Swift 4.2 (Xcode 10), we can do this

#if targetEnvironment(simulator)
  //simulator code
#else 
  #warning("Not compiling for simulator")
#endif

Updated code:

This is purported to work officially.

#if TARGET_IPHONE_SIMULATOR
NSString *hello = @"Hello, iPhone simulator!";
#elif TARGET_OS_IPHONE
NSString *hello = @"Hello, device!";
#else
NSString *hello = @"Hello, unknown target!";
#endif

Original post (since deprecated)

This code will tell you if you are running in a simulator.

#ifdef __i386__
NSLog(@"Running in the simulator");
#else
NSLog(@"Running on a device");
#endif

In case of Swift we can implement following

We can create struct which allows you to create a structured data

struct Platform {
    static var isSimulator: Bool {
        #if targetEnvironment(simulator)
            // We're on the simulator
            return true
        #else
            // We're on a device
             return false
        #endif
    }
}

Then If we wanted to Detect if app is being built for device or simulator in Swift then .

if Platform.isSimulator {
    // Do one thing
} else {
    // Do the other
}

Has anyone considered the answer provided here?

I suppose the objective-c equivalent would be

+ (BOOL)isSimulator {
    NSOperatingSystemVersion ios9 = {9, 0, 0};
    NSProcessInfo *processInfo = [NSProcessInfo processInfo];
    if ([processInfo isOperatingSystemAtLeastVersion:ios9]) {
        NSDictionary<NSString *, NSString *> *environment = [processInfo environment];
        NSString *simulator = [environment objectForKey:@"SIMULATOR_DEVICE_NAME"];
        return simulator != nil;
    } else {
        UIDevice *currentDevice = [UIDevice currentDevice];
        return ([currentDevice.model rangeOfString:@"Simulator"].location != NSNotFound);
    }
}

For Swift 4.2 / xCode 10

I created an extension on UIDevice, so I can easily ask for if the simulator is running.

// UIDevice+CheckSimulator.swift

import UIKit

extension UIDevice {

    /// Checks if the current device that runs the app is xCode's simulator
    static func isSimulator() -> Bool {        
        #if targetEnvironment(simulator)
            return true
        #else
            return false
        #endif
    }
}

In my AppDelegate for example I use this method to decide wether registering for remote notification is necessary, which is not possible for the simulator.

// CHECK FOR REAL DEVICE / OR SIMULATOR
if UIDevice.isSimulator() == false {

    // REGISTER FOR SILENT REMOTE NOTIFICATION
    application.registerForRemoteNotifications()
}

I had the same problem, both TARGET_IPHONE_SIMULATOR and TARGET_OS_IPHONE are always defined, and are set to 1. Pete's solution works, of course, but if you ever happen to build on something other than intel (unlikely, but who knows), here's something that's safe as long as the iphone hardware doesn't change (so your code will always work for the iphones currently out there):

#if defined __arm__ || defined __thumb__
#undef TARGET_IPHONE_SIMULATOR
#define TARGET_OS_IPHONE
#else
#define TARGET_IPHONE_SIMULATOR 1
#undef TARGET_OS_IPHONE
#endif

Put that somewhere convenient, and then pretend that the TARGET_* constants were defined correctly.


All those answer are good, but it somehow confuses newbie like me as it does not clarify compile check and runtime check. Preprocessor are before compile time, but we should make it clearer

This blog article shows How to detect the iPhone simulator? clearly

Runtime

First of all, let’s shortly discuss. UIDevice provides you already information about the device

[[UIDevice currentDevice] model]

will return you “iPhone Simulator” or “iPhone” according to where the app is running.

Compile time

However what you want is to use compile time defines. Why? Because you compile your app strictly to be run either inside the Simulator or on the device. Apple makes a define called TARGET_IPHONE_SIMULATOR. So let’s look at the code :

#if TARGET_IPHONE_SIMULATOR

NSLog(@"Running in Simulator - no app store or giro");

#endif

Apple has added support for checking the app is targeted for the simulator with the following:

#if targetEnvironment(simulator)
let DEVICE_IS_SIMULATOR = true
#else
let DEVICE_IS_SIMULATOR = false
#endif

This worked for me best

NSString *name = [[UIDevice currentDevice] name];


if ([name isEqualToString:@"iPhone Simulator"]) {

}

if nothing worked, try this

public struct Platform {

    public static var isSimulator: Bool {
        return TARGET_OS_SIMULATOR != 0 // Use this line in Xcode 7 or newer
    }

}

The previous answers are a little dated. I found that all you need to do is query the TARGET_IPHONE_SIMULATOR macro (no need to include any other header files [assuming you are coding for iOS]).

I attempted TARGET_OS_IPHONE but it returned the same value (1) when running on an actual device and simulator, that's why I recommend using TARGET_IPHONE_SIMULATOR instead.


My answer is based on @Daniel Magnusson answer and comments of @Nuthatch and @n.Drake. and I write it to save some time for swift users working on iOS9 and onwards.

This is what worked for me:

if UIDevice.currentDevice().name.hasSuffix("Simulator"){
    //Code executing on Simulator
} else{
    //Code executing on Device
}

The best way to do this is:

#if TARGET_IPHONE_SIMULATOR

and not

#ifdef TARGET_IPHONE_SIMULATOR

since its always defined: 0 or 1


if nothing worked, try this

public struct Platform {

    public static var isSimulator: Bool {
        return TARGET_OS_SIMULATOR != 0 // Use this line in Xcode 7 or newer
    }

}

THERE IS A BETTER WAY NOW!

As of Xcode 9.3 beta 4 you can use #if targetEnvironment(simulator) to check.

#if targetEnvironment(simulator)
//Your simulator code
#endif

UPDATE
Xcode 10 and iOS 12 SDK supports this too.


To include all types of "simulators"

NSString *model = [[UIDevice currentDevice] model];
if([model rangeOfString:@"Simulator" options:NSCaseInsensitiveSearch].location !=NSNotFound)
{
    // we are running in a simulator
}

Works for Swift 5 and Xcode 12

Use this code:

#if targetEnvironment(simulator)
   // Simulator
#else
   // Device
#endif

This worked for me best

NSString *name = [[UIDevice currentDevice] name];


if ([name isEqualToString:@"iPhone Simulator"]) {

}

/// Returns true if its simulator and not a device

public static var isSimulator: Bool {
    #if (arch(i386) || arch(x86_64)) && os(iOS)
        return true
    #else
        return false
    #endif
}

In case of Swift we can implement following

We can create struct which allows you to create a structured data

struct Platform {
    static var isSimulator: Bool {
        #if targetEnvironment(simulator)
            // We're on the simulator
            return true
        #else
            // We're on a device
             return false
        #endif
    }
}

Then If we wanted to Detect if app is being built for device or simulator in Swift then .

if Platform.isSimulator {
    // Do one thing
} else {
    // Do the other
}

Updated code:

This is purported to work officially.

#if TARGET_IPHONE_SIMULATOR
NSString *hello = @"Hello, iPhone simulator!";
#elif TARGET_OS_IPHONE
NSString *hello = @"Hello, device!";
#else
NSString *hello = @"Hello, unknown target!";
#endif

Original post (since deprecated)

This code will tell you if you are running in a simulator.

#ifdef __i386__
NSLog(@"Running in the simulator");
#else
NSLog(@"Running on a device");
#endif

All those answer are good, but it somehow confuses newbie like me as it does not clarify compile check and runtime check. Preprocessor are before compile time, but we should make it clearer

This blog article shows How to detect the iPhone simulator? clearly

Runtime

First of all, let’s shortly discuss. UIDevice provides you already information about the device

[[UIDevice currentDevice] model]

will return you “iPhone Simulator” or “iPhone” according to where the app is running.

Compile time

However what you want is to use compile time defines. Why? Because you compile your app strictly to be run either inside the Simulator or on the device. Apple makes a define called TARGET_IPHONE_SIMULATOR. So let’s look at the code :

#if TARGET_IPHONE_SIMULATOR

NSLog(@"Running in Simulator - no app store or giro");

#endif

In swift :

#if (arch(i386) || arch(x86_64))
...            
#endif

From Detect if app is being built for device or simulator in Swift


The best way to do this is:

#if TARGET_IPHONE_SIMULATOR

and not

#ifdef TARGET_IPHONE_SIMULATOR

since its always defined: 0 or 1


In my opinion, the answer (presented above and repeated below):

NSString *model = [[UIDevice currentDevice] model];
if ([model isEqualToString:@"iPhone Simulator"]) {
    //device is simulator
}

is the best answer because it is obviously executed at RUNTIME versus being a COMPILE DIRECTIVE.


Works for Swift 5 and Xcode 12

Use this code:

#if targetEnvironment(simulator)
   // Simulator
#else
   // Device
#endif

Updated code:

This is purported to work officially.

#if TARGET_IPHONE_SIMULATOR
NSString *hello = @"Hello, iPhone simulator!";
#elif TARGET_OS_IPHONE
NSString *hello = @"Hello, device!";
#else
NSString *hello = @"Hello, unknown target!";
#endif

Original post (since deprecated)

This code will tell you if you are running in a simulator.

#ifdef __i386__
NSLog(@"Running in the simulator");
#else
NSLog(@"Running on a device");
#endif

The previous answers are a little dated. I found that all you need to do is query the TARGET_IPHONE_SIMULATOR macro (no need to include any other header files [assuming you are coding for iOS]).

I attempted TARGET_OS_IPHONE but it returned the same value (1) when running on an actual device and simulator, that's why I recommend using TARGET_IPHONE_SIMULATOR instead.


Examples related to ios

Adding a UISegmentedControl to UITableView Crop image to specified size and picture location Undefined Symbols error when integrating Apptentive iOS SDK via Cocoapods Keep placeholder text in UITextField on input in IOS Accessing AppDelegate from framework? Autoresize View When SubViews are Added Warp \ bend effect on a UIView? Speech input for visually impaired users without the need to tap the screen make UITableViewCell selectable only while editing Xcode 12, building for iOS Simulator, but linking in object file built for iOS, for architecture arm64

Examples related to objective-c

Adding a UISegmentedControl to UITableView Keep placeholder text in UITextField on input in IOS Accessing AppDelegate from framework? Warp \ bend effect on a UIView? Use NSInteger as array index Detect if the device is iPhone X Linker Command failed with exit code 1 (use -v to see invocation), Xcode 8, Swift 3 ITSAppUsesNonExemptEncryption export compliance while internal testing? How to enable back/left swipe gesture in UINavigationController after setting leftBarButtonItem? Change status bar text color to light in iOS 9 with Objective-C

Examples related to swift

Make a VStack fill the width of the screen in SwiftUI Xcode 10.2.1 Command PhaseScriptExecution failed with a nonzero exit code Command CompileSwift failed with a nonzero exit code in Xcode 10 Convert Json string to Json object in Swift 4 iOS Swift - Get the Current Local Time and Date Timestamp Xcode 9 Swift Language Version (SWIFT_VERSION) How do I use Safe Area Layout programmatically? How can I use String substring in Swift 4? 'substring(to:)' is deprecated: Please use String slicing subscript with a 'partial range from' operator Safe Area of Xcode 9 The use of Swift 3 @objc inference in Swift 4 mode is deprecated?

Examples related to xcode

Undefined Symbols error when integrating Apptentive iOS SDK via Cocoapods Xcode 12, building for iOS Simulator, but linking in object file built for iOS, for architecture arm64 iPhone is not available. Please reconnect the device Make a VStack fill the width of the screen in SwiftUI error Failed to build iOS project. We ran "xcodebuild" command but it exited with error code 65 The iOS Simulator deployment targets is set to 7.0, but the range of supported deployment target version for this platform is 8.0 to 12.1 Xcode 10.2.1 Command PhaseScriptExecution failed with a nonzero exit code Git is not working after macOS Update (xcrun: error: invalid active developer path (/Library/Developer/CommandLineTools) Xcode 10: A valid provisioning profile for this executable was not found Xcode 10, Command CodeSign failed with a nonzero exit code

Examples related to ios-simulator

The iOS Simulator deployment targets is set to 7.0, but the range of supported deployment target version for this platform is 8.0 to 12.1 flutter run: No connected devices Error Running React Native App From Terminal (iOS) How to uninstall downloaded Xcode simulator? Capture iOS Simulator video for App Preview iPhone 6 Plus resolution confusion: Xcode or Apple's website? for development How to enable native resolution for apps on iPhone 6 and 6 Plus? How to access iOS simulator camera Error Domain=NSURLErrorDomain Code=-1005 "The network connection was lost." Document directory path of Xcode Device Simulator