【问题标题】:React Native: How can I detect if my code is running in the Simulator?React Native:如何检测我的代码是否在模拟器中运行?
【发布时间】:2016-04-16 03:19:19
【问题描述】:

在一个 Obj-C iOS 应用程序中,我可以使用 #if (TARGET_IPHONE_SIMULATOR) 编写仅限模拟器的代码。

在 react native 中我可以使用:

if (__DEV__) {
 .. do something special
}

.. 检测开发模式。

我们可以使用Platform.OS === 'ios' 来检测平台(Android/iOS)。 请参阅此处了解更多信息Platform Docs

但是我们如何检测应用程序是否在模拟器中运行?

我问的原因是我的应用程序使用相机扫描条形码,而 iOS 模拟器不支持。

【问题讨论】:

    标签: android ios react-native


    【解决方案1】:

    我能想到的最简单的解决方案,不需要创建原生模块(或修改现有模块),就是将此参数作为反应组件属性传递。

    在初始化RCTRootViewAppDelegate 中,检查它是否是模拟器,就像在常规iOS 应用程序中一样;然后将此信息作为 initialProperties 传递给反应根视图:

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

    现在你可以通过你的 react 组件的 props 在 JavaScript 中访问它:

    this.props.isSimulator
    

    在 Android 上,在 MainActivity 中扩展 ReactActivity 您可以使用类似的方法:

    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;
    }
    

    【讨论】:

    • 嘿,很棒的解决方案,它就像一个魅力。您是否还有关于如何在 Android 上运行的代码 sn-p?
    • @SebastianGermesin 我更新了答案以显示使用类似方法的 Android 解决方案。
    • 在最新的 RN (0.63.x),using createReactActivityDelegate works.
    • 我还需要添加这样一行:|| Build.MODEL.contains("sdk_gphone")
    【解决方案2】:

    您可以使用react-native-device-info 轻松完成此操作,如下所示:

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

    【讨论】:

    • .getModel() 在 android 上也有同样的结果吗?哪个是“模拟器”?
    • 对不起,我不知道,我对 Android 做的不多!好问题!
    • 这不适用于安卓模拟器(至少在我的)
    • 使用 DeviceInfo.isEmulator() 代替。我已经编辑了答案。
    • @BrunoLemos 我认为您的编辑没有被保存/接受
    【解决方案3】:
    import getHostForRN from 'rn-host-detect';
    const IS_SIMULATOR = getHostForRN('127.0.0.1') == "localhost";
    

    这有助于区分我的 iOS 模拟器和我的实际设备,因为模拟器返回 localhost 而 iOS 设备返回 127.0.0.1。尚未在 Android 上测试过,但如果对你们有帮助,请告诉我。

    【讨论】:

      【解决方案4】:

      如果您正在构建 CRNA/Expo 应用程序,您可以使用 Expo.Constants.isDevice https://docs.expo.io/versions/latest/sdk/constants/#constantsisdevice

      import { Constants } from 'expo'
      //....
      
      console.log(Constants.isDevice) // => false if simulator
      

      【讨论】:

      【解决方案5】:

      使用react-native-device-info可以得到以下数据(在模拟器上执行):

      getUniqueID: DB71DCB5-6BB0-497B-BE9E-A02BCC1235B7
      getInstanceID: undefined
      getDeviceId: x86_64
      getManufacturer: Apple
      getModel: Simulator
      getBrand: Apple
      getSystemName: iOS
      getSystemVersion: 10.1
      getBundleId: org.reactjs.native.example.project
      getBuildNumber: 1
      getVersion: 1.0
      getReadableVersion: 1.0.1
      getDeviceName:MacBook Pro
      getUserAgent: Mozilla/5.0 (iPhone; CPU iPhone OS 10_1 like Mac OS X) AppleWebKit/602.2.14 (KHTML, like Gecko) Mobile/14B72
      getDeviceLocale: en
      getDeviceCountry: US
      getTimezone: America/Panama
      isEmulator: true
      isTablet: false
      

      【讨论】:

      • 有用的信息,谢谢。现在避免阅读文档。
      【解决方案6】:

      目前,没有任何方法可以查看您是否在 JS 中从模拟器运行。

      我建议添加条件TARGET_IPHONE_SIMULATOR 来签入您的本机代码(如果您编写了自己的模块)。或者,如果在模拟器中,可能使用不渲染相机的第 3 方模块......即:react-native-camera:https://github.com/lwansbrough/react-native-camera/search?utf8=%E2%9C%93&q=TARGET_IPHONE_SIMULATOR

      【讨论】:

        猜你喜欢
        • 2012-05-11
        • 1970-01-01
        • 2015-06-09
        • 1970-01-01
        • 1970-01-01
        • 2019-01-23
        • 1970-01-01
        • 2016-11-29
        • 2017-04-18
        相关资源
        最近更新 更多