React Native: How can I detect if my code is running in the Simulator?

In a Obj-C iOS app I can use #if (TARGET_IPHONE_SIMULATOR) to write simulator-only code.

In react native I can use:

if (__DEV__) {
 .. do something special
}

.. to detect development mode.

We can use Platform.OS === 'ios' to detect the platform (Android/iOS). See here for more info Platform Docs

But how do we detect if the app is running in the simulator?

The reason I ask is that my app uses the camera to scan barcodes, and this isn't supported in the iOS Simulator.


You can do this pretty easily with react-native-device-info, like so:

import DeviceInfo from 'react-native-device-info'

isSimulator() {
  // https://github.com/react-native-community/react-native-device-info#isemulator
  return DeviceInfo.isEmulator();
},

The easiest solution I can think of, which does not require creating a native module (or modifying an existing one), would be to pass this parameter as a react component property.

In your AppDelegate where the RCTRootView is initialized, you check if it's the simulator as you would do in a regular iOS app; you then pass this info to the react root-view as its initialProperties:

  BOOL isSimulator = NO;
#if TARGET_IPHONE_SIMULATOR
  isSimulator = YES;
#endif
  
  RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation
                                                      moduleName:@"ReactDemo"
                                               initialProperties:@{@"isSimulator": @(isSimulator)}
                                                   launchOptions:launchOptions];

Now you can access it in the JavaScript via the props of your react component:

this.props.isSimulator

On Android, in you MainActivity which extends ReactActivity you can use a similar approach:

import android.os.Build;
import android.os.Bundle;

public boolean isEmulator() {
        return Build.FINGERPRINT.startsWith("generic")
                || Build.FINGERPRINT.startsWith("unknown")
                || Build.MODEL.contains("google_sdk")
                || Build.MODEL.contains("Emulator")
                || Build.MODEL.contains("Android SDK built for x86")
                || Build.MANUFACTURER.contains("Genymotion")
                || (Build.BRAND.startsWith("generic") && Build.DEVICE.startsWith("generic"))
                || "google_sdk".equals(Build.PRODUCT);
    }

@Override
protected Bundle getLaunchOptions() {
    Bundle opts = new Bundle();
    opts.putBoolean("isEmulator", isEmulator());
    return opts;
}