How to Detect If App Is Being Built For Device or Simulator in Swift

How to detect if app is being built for device or simulator in Swift

Update 30/01/19

While this answer may work, the recommended solution for a static check (as clarified by several Apple engineers) is to define a custom compiler flag targeting iOS Simulators. For detailed instructions on how to do to it, see @mbelsky's answer.

Original answer

If you need a static check (e.g. not a runtime if/else) you can't detect the simulator directly, but you can detect iOS on a desktop architecture like follows

#if (arch(i386) || arch(x86_64)) && os(iOS)
...
#endif

After Swift 4.1 version

Latest use, now directly for all in one condition for all types of simulators need to apply only one condition -

#if targetEnvironment(simulator)
// your simulator code
#else
// your real device code
#endif

For more clarification, you can check Swift proposal SE-0190


For older version -

Clearly, this is false on a device, but it returns true for the iOS Simulator, as specified in the documentation:

The arch(i386) build configuration returns true when the code is compiled for the 32–bit iOS simulator.

If you are developing for a simulator other than iOS, you can simply vary the os parameter: e.g.

Detect the watchOS simulator

#if (arch(i386) || arch(x86_64)) && os(watchOS)
...
#endif

Detect the tvOS simulator

#if (arch(i386) || arch(x86_64)) && os(tvOS)
...
#endif

Or, even, detect any simulator

#if (arch(i386) || arch(x86_64)) && (os(iOS) || os(watchOS) || os(tvOS))
...
#endif

If you instead are ok with a runtime check, you can inspect the TARGET_OS_SIMULATOR variable (or TARGET_IPHONE_SIMULATOR in iOS 8 and below), which is truthy on a simulator.

Please notice that this is different and slightly more limited than using a preprocessor flag. For instance you won't be able to use it in place where a if/else is syntactically invalid (e.g. outside of functions scopes).

Say, for example, that you want to have different imports on the device and on the simulator. This is impossible with a dynamic check, whereas it's trivial with a static check.

#if (arch(i386) || arch(x86_64)) && os(iOS)
import Foo
#else
import Bar
#endif

Also, since the flag is replaced with a 0 or a 1 by the swift preprocessor, if you directly use it in a if/else expression the compiler will raise a warning about unreachable code.

In order to work around this warning, see one of the other answers.

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

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.

How to detect app is running on simulator or device

Keep in mind UIDevice provides you already with information about the device itself.

[[UIDevice currentDevice] model]

You can also use the following:

TARGET_IPHONE_SIMULATOR tells you if you're in the iPhone simulator.

TARGET_OS_IPHONE tells you that you're working on the iPhone instead of MacOS.

#if TARGET_IPHONE_SIMULATOR

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

#else

NSLog(@"Running on the Device");

#endif

and when ONLY interested in the device

#if !(TARGET_IPHONE_SIMULATOR)

NSLog(@"Running on device");

#endif

Programmatically detect if app is being run on device or simulator

#if TARGET_OS_SIMULATOR

//Simulator

#else

// Device

#endif

Pls refer this previous SO question also What #defines are set up by Xcode when compiling for iPhone

How to detect in runtime that app uses swift

Please find below the possible approach based on public documented dyld API available since iPhone2 and valid for all modern iOS versions. And libswiftCore.dylib is present always for swift.

Taking into account that Swift might be in some application plug-ins, the below function should be called regularly (or at least till first positive result) on your framework API call.

#import 

BOOL isSwiftLoaded() {
return NSVersionOfRunTimeLibrary("libswiftCore.dylib") != -1;
// -1 is documented indicator that library is not loaded
}

Check if Apple LiveText is available?

Don't check for the iOS 15+ and processor A12+, check for the iOS 15's 'Live Text'feature support. Create a helper method with the following check that will return whether the device support live text or not



Sample:

var isSupported = true
if #available(iOS 15.0, *) {
let check = UITextField().canPerformAction(#selector(UIResponder.captureTextFromCamera(_:)), withSender: nil)
isSupported = check
} else {
isSupported = false
}

print(isSupported)

Using the above condition will return false in the case of the device having iOS 15+ but not having hardware support.



Related Topics



Leave a reply



Submit