views:

5312

answers:

4

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.

+6  A: 

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

That could be problematic based on if some things on the platform change. This is also 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
Pete
+19  A: 

Already asked, but with a very different title.

http://stackoverflow.com/questions/146986/what-defines-are-setup-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 definitions are TARGET_OS_IPHONE and TARGET_IPHONE_SIMULATOR, which will be defined provided that you

#include "TargetConditionals.h"

Since that won't exist on non apple platforms, you can wrap your include like this

#ifdef __APPLE__
   #include "TargetConditionals.h"
#endif

before including that file

So, for example, if you want to check that you are running on device, you should do

#if !(TARGET_IPHONE_SIMULATOR)
Airsource Ltd
Thanks. 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.
Jeffrey Meyer
Yes, 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.
Airsource Ltd
Be 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).
Stream
Correct, 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).
Airsource Ltd
Watch the #if and #ifdef difference. For me it was the cause of incorrect behavior.
Anton
+1  A: 

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.

A: 

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

NSString *model= [[UIDevice currentDevice] model];
NSString *iPhoneSimulator = @”iPhone Simulator”;

if ([model compare:iPhoneSimulator] == NSOrderedSame){
//device is simulator
}
Daniel T. Magnusson