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
In swift :
#if (arch(i386) || arch(x86_64))
...
#endif
From Detect if app is being built for device or simulator in Swift
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
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
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
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
}
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
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
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
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.
Source: Stackoverflow.com