You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Native iOS中如何区分飞行模式与无服务状态?

React Native iOS 区分飞行模式与无运营商信号的解决方案

针对你的业务需求(阻止用户用飞行模式绕过功能),以下是可行的iOS端实现方案,结合你当前使用的依赖版本(react-native@0.64.0、@react-native-community/netinfo@6.0.0、react-native-system-setting@1.7.6):

核心问题说明

iOS系统没有开放直接读取飞行模式状态的API给第三方应用,而@react-native-community/netinfo和react-native-system-setting无法直接区分「无运营商信号」和「飞行模式」——两种场景都会返回无网络状态。因此需要通过原生API间接推断。


方案一:自定义原生模块调用CoreTelephony框架

通过iOS原生的CoreTelephony框架获取运营商信息,结合网络状态间接判断是否为飞行模式,这是最可靠的方式。

步骤1:创建iOS原生模块

在你的React Native项目的iOS目录下,新建NetworkStatusModule.h和NetworkStatusModule.m文件:

NetworkStatusModule.h

#import <React/RCTBridgeModule.h>

@interface RCT_EXTERN_MODULE(NetworkStatusModule, NSObject)
RCT_EXTERN_METHOD(getNetworkDetails:(RCTResponseSenderBlock)callback)
@end

NetworkStatusModule.m

#import "NetworkStatusModule.h"
#import <CoreTelephony/CTTelephonyNetworkInfo.h>
#import <CoreTelephony/CTCarrier.h>

@implementation NetworkStatusModule

RCT_EXPORT_METHOD(getNetworkDetails:(RCTResponseSenderBlock)callback) {
    CTTelephonyNetworkInfo *networkInfo = [[CTTelephonyNetworkInfo alloc] init];
    CTCarrier *carrier = networkInfo.subscriberCellularProvider;
    
    // 判断是否能检测到运营商信息
    BOOL hasValidCarrier = carrier != nil && carrier.mobileNetworkCode.length > 0;
    // 判断是否有蜂窝网络连接
    BOOL hasCellularConnection = NO;
    NSArray *radioStatuses = networkInfo.serviceCurrentRadioAccessTechnology.allValues;
    for (NSString *status in radioStatuses) {
        if (status.length > 0) {
            hasCellularConnection = YES;
            break;
        }
    }
    
    // 推断飞行模式:无蜂窝连接 + 无有效运营商信息(排除手动关闭蜂窝的情况)
    BOOL isFlightMode = !hasCellularConnection && !hasValidCarrier;
    
    callback(@[@{
        @"isFlightMode": @(isFlightMode),
        @"hasValidCarrier": @(hasValidCarrier),
        @"hasCellularConnection": @(hasCellularConnection)
    }]);
}

@end

步骤2:在React Native中调用

在JS代码中引入原生模块并使用:

import { NativeModules } from 'react-native';
const { NetworkStatusModule } = NativeModules;

// 检测网络状态的方法
const checkNetworkType = async () => {
  try {
    const details = await NetworkStatusModule.getNetworkDetails();
    if (details.isFlightMode) {
      // 处理飞行模式场景:比如弹窗提示阻止用户操作
      alert("请关闭飞行模式以使用该功能");
    } else if (!details.hasCellularConnection && details.hasValidCarrier) {
      // 无运营商信号场景:可提示用户检查信号
      alert("当前无运营商信号,请稍后重试");
    }
  } catch (error) {
    console.error("网络状态检测失败:", error);
  }
};

// 在需要检测的时机调用(比如进入特定页面、触发功能前)
checkNetworkType();

权限配置

在Info.plist中添加蜂窝网络权限描述:

<key>NSCellularNetworkUsageDescription</key>
<string>需要访问蜂窝网络以验证网络状态</string>

方案二:结合现有依赖的补充判断(仅作辅助)

如果暂时不想写原生代码,可以结合react-native-system-setting的蜂窝开关状态,辅助缩小判断范围:

import NetInfo from '@react-native-community/netinfo';
import SystemSetting from 'react-native-system-setting';

const checkNetworkStatus = async () => {
  const netInfo = await NetInfo.fetch();
  const isCellularEnabled = await SystemSetting.getCellularEnabled();
  
  if (!netInfo.isConnected) {
    if (!isCellularEnabled) {
      // 蜂窝数据被关闭,但无法区分是手动关闭还是飞行模式,需结合原生模块进一步判断
      console.log("蜂窝数据已关闭");
    } else {
      // 蜂窝数据开启但无网络,可能是无信号或飞行模式,需原生模块确认
      console.log("蜂窝数据开启但无网络");
    }
  }
};

注意:该方法无法100%区分两种状态,仅作辅助,最终可靠判断仍需依赖原生模块。


关键注意事项

  1. iOS版本兼容:CoreTelephony的API在iOS 12+均稳定,适配你的RN 0.64.0无问题;
  2. 飞行模式推断逻辑:由于iOS限制,只能通过「无蜂窝连接+无运营商信息」间接判断,已覆盖绝大多数场景;
  3. 测试场景:需分别测试「飞行模式开启」「无信号区域」「手动关闭蜂窝数据」三种场景,确保逻辑准确。

内容的提问来源于stack exchange,提问作者lsilva

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 19:25:19