How can I programmatically determine if my app is running in the iphone simulator?
Solution 1
Already asked, but with a very different title.
What #defines are set up by Xcode when compiling for iPhone
I'll repeat my answer from there:
It's in the SDK docs under "Compiling source code conditionally"
The relevant definition is TARGET_OS_SIMULATOR, which is defined in /usr/include/TargetConditionals.h within the iOS framework. On earlier versions of the toolchain, you had to write:
#include "TargetConditionals.h"
but this is no longer necessary on the current (Xcode 6/iOS8) toolchain.
So, for example, if you want to check that you are running on device, you should do
#if TARGET_OS_SIMULATOR
// Simulator-specific code
#else
// Device-specific code
#endif
depending on which is appropriate for your use-case.
Solution 2
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
Solution 3
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
}
Solution 4
The best way to do this is:
#if TARGET_IPHONE_SIMULATOR
and not
#ifdef TARGET_IPHONE_SIMULATOR
since its always defined: 0 or 1
Solution 5
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.
Related videos on Youtube
Comments
-
Jeffrey Meyer over 3 years
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.
-
WiseOldDuck about 8 yearsI'm not sure a pre-processor directive is dynamic (though it might be what you were looking for anyway). The directive means that you actually knew, when you built it, where it was going to wind up running.
-
rustyMagnet over 3 yearsAs I know my target is only a new iPhone or Simulator, I like
__x86_64__
( iPhone simulator ) and__arm64__
( iPhone device )
-
-
Jeffrey Meyer over 15 yearsThanks. I agree with you this is a more specific version of your original question. If yours had come up in my original search, I wouldn't have even needed to ask.
-
Airsource Ltd over 15 yearsYes, I appreciate that it doesn't show up easily in a search - I was just referencing it as a duplicate so that people could read comments in both places.
-
Vadim over 15 yearsBe careful with these definitions. When you compile code with menu item 'Project > Set Active SDK > Simulator…', as TARGET_IPHONE_SIMULATOR as TARGET_OS_IPHONE variables are both defined! So the only right way to separate logic is pointed out below by Pete (Thanks dude).
-
Airsource Ltd over 15 yearsCorrect, but when you compile for device, TARGET_IPHONE_SIMULATOR is not set, so why not just switch on that? Switching on i386 relies on the toolchain defs, and will be invalid if compiling on a non-x86 platform (not currently possibly, of course).
-
Anton over 14 yearsWatch the #if and #ifdef difference. For me it was the cause of incorrect behavior.
-
user102008 over 13 years
[model compare:iPhoneSimulator] == NSOrderedSame
should be written as[model isEqualToString:iPhoneSimulator]
-
cyrilchampier almost 12 yearsas said here: stackoverflow.com/questions/3742525/… it is not true for static libraries
-
nine stones over 10 yearsI disagree. This code ends up in your product, whereas a compiler directive keeps the - on the device unnecessary - routine out.
-
dmur about 10 yearsPerhaps the need to include TargetConditionals has been obviated since this was written, but just wanted to note that #if TARGET_IPHONE_SIMULATOR works without including TargetConditionals.h now.
-
Brad Parks about 10 yearsThe compiler directives work because the device and simulators are completely different compile targets - ie you wouldn't use the same binary on both. It has to be compiled to different hardware, so it makes sense in that case.
-
mmmmmm almost 10 yearsHow does this improve on other answers?
-
onmyway133 almost 10 years@Mark It clarifies a little bit
-
Nuthatch almost 10 yearsOr
[model hasSuffix:@"Simulator"]
if you only care about "simulator" in general, not iPhone or iPad in particular. This answer won't work for iPad simulator :) -
malhal over 9 yearsAs of iOS 8 and Xcode 6.1.1 the TARGET_OS_IPHONE is true on the simulator.
-
Le Mot Juiced about 9 yearsUpvoted because Nuthatch's comment makes this the best answer in toto.
-
JoJo almost 9 yearsWouldn't it better to use the regular
if
instead of the pre-processor#if
so that you have to potential to get compiler errors in both control paths? The pre-processor#if
doesn't compile the branch that you're currently not targeting. You wouldn't want to have a false sense of accomplishment when all your code works on the simulator, but your real device branch is broken. -
Airsource Ltd almost 9 yearsYou may be #if-ing code that doesn't actually compile on one platform or the other, but yes, you could use if. Not sure how this helps with the false sense of achievement, you would still need to test it on both platforms!
-
nsinvocation over 8 yearsIt has nothing to do with Xcode 7. If you run iOS Simulator with iOS8 (from Xcode 7) then this will work. It won't work for iOS9 where [[UIDevice currentDevice] model] returns only "iPhone" if app was launched from iOS Simulator
-
n.Drake over 8 yearsIn iOS9, check the device
name
instead ofmodel
-
eMdOS over 8 yearsCurrently, in Xcode 7, iOS 9 Simulator
[[UIDevice currentDevice] model]
is returningiPhone
also instead ofiPhone Simulator
. So, I think this is not the best approach. -
Fabio Napodano over 8 yearsthis doesn't worik anymore on newer XCode versions
-
gnasher729 about 8 yearsUnless you are in 2016 and run a 64 bit simulator. Or in 2019 and run your code on an iPhone with Intel processor.
-
gnasher729 about 8 yearsTARGET_OS_IPHONE is for code that might run on iOS or on MacOS X. Obviously you would want that code to behave the "iPhone" way on a simulator.
-
gnasher729 about 8 yearsBeing executed at RUNTIME makes it the worst possible answer.
-
Dimitris about 8 yearsWhy the parentheses ( ) around TARGET_OS_SIMULATOR?
-
mbelsky about 8 yearsThe code won't work if a user adds
Simulator
word in his device name -
mbelsky about 8 yearsThe code won't work if a user adds
Simulator
word in his device name -
Eric about 8 yearsOn Xcode 7.3, iPhone 6 Plus Simulator returns
"iPhone"
. -
Iron John Bonney almost 8 yearsCleanest implementation in my opinion, and it accounts for x86_64 and i386 architectures. Helped me overcome a weird device vs. simulator bug in Core Data. You're the man!
-
Andrew Duncan almost 8 yearsI needed the include in an Obj-C file for iOS 9 using Xcode 7. Hmm.
-
Michael over 7 yearsUnfortunately with XCode 8
UIDevice.current.name
reports the name of the machine the Simulator is running on (typically something like "Simon's MacBook Pro" now) so the test has become unreliable. I am still looking into a clean way to fix it. -
Bobjt over 7 yearsTo distinguish between mac apps: #if ( arch( i386 ) || arch( x86_64 ) ) && !os( OSX ) // we’re on a simulator running on mac, and not a mac app. (For cross platforms code included in mac targets)
-
Gobe over 7 yearswhy not
-[NSString containsString]
? -
Airsource Ltd about 7 years@Oren see stackoverflow.com/questions/24869481/…
-
Airsource Ltd about 7 years@Dimitris It's good practice. You don't know how TARGET_OS_SIMULATOR has been defined, so !(TARGET_OS_SIMULATOR) may not be identical to !TARGET_OS_SIMULATOR
-
DawnSong over 6 yearsIn Playground, you will get a warning, "Code after 'return' will never be executed". So I think
#if #else #endif
will be better. -
Vrutin Rathod about 6 yearsThis is the only that works for me, rest of the solutions didn't work.
-
Stefan Vasiljevic over 5 yearsThere is a better way to do this now. See my answer in this thread stackoverflow.com/a/49236898/2272561
-
J. Doe over 5 yearsJust another copy paste
-
Matt S. about 4 yearsNote This is only in swift.