iOS网络监听:大陆国行与非大陆国行区别

网络监听

Posted by PaysonChen on June 6, 2025

1、背景

首次安装应用,存在需要点击“允许xxx使用无线数据”的弹窗,点击允许后才有网络权限。

1

一些首次配置的联网操作需要此弹窗后进行,于是我们需要进行网络监听:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
/// 开始监听
- (void)startMonitoringWithCallback:(void (^)(PSCAppNetworkStatus status))callback {
    if (!callback) return;

    nw_path_monitor_set_update_handler(_monitor, ^(nw_path_t path) {
        PSCAppNetworkStatus status = NetworkStatusUnavailable;

        if (nw_path_get_status(path) == nw_path_status_satisfied) {
            BOOL usesWiFi = nw_path_uses_interface_type(path, nw_interface_type_wifi);
            BOOL usesCellular = nw_path_uses_interface_type(path, nw_interface_type_cellular);
            
            if (usesWiFi && usesCellular) {
                status = NetworkStatusWiFiCellular;
            } else if (usesWiFi) {
                status = NetworkStatusWiFi;
            } else if (usesCellular) {
                status = NetworkStatusCellular;
            }
        }
        callback(status); // 回调网络状态
    });

    nw_path_monitor_start(_monitor);
}

2、问题

​ 一开始在大多数设备上验证没有问题,直到出现了一台测试机回调无法触发,大多数版本的设备,首次启动弹出上图“允许xxx使用无线数据”的弹窗。这台设备首次安装一直没有弹出。

​ 通过查资料发现,不同版本设备在网络权限的使用上不一样。

3

大陆版 设置->xxApp

4

海外版 设置->xxApp

海外版设备在关闭了蜂窝数据后,在未开启wifi的情况下的弹窗是这样的:

2

3、解决

​ 海外版设备,在网络发生切换时,会进入:nw_path_monitor_set_update_handler回调,而首次安装并打开不会。

​ 大陆版设备,在网络切换 以及 首次安装打开,均会触发nw_path_monitor_set_update_handler回调。

​ 为了兼容海外版场景,在开始监听后,判断网络是否为可联通,如果可联通。则回调出可联通的状态

代码修改如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
/// 开始监听
- (void)startMonitoringWithCallback:(void (^)(PSCAppNetworkStatus status))callback {
    if (!callback) return;

    nw_path_monitor_set_update_handler(_monitor, ^(nw_path_t path) {
        PSCAppNetworkStatus status = NetworkStatusUnavailable;

        if (nw_path_get_status(path) == nw_path_status_satisfied) {
            BOOL usesWiFi = nw_path_uses_interface_type(path, nw_interface_type_wifi);
            BOOL usesCellular = nw_path_uses_interface_type(path, nw_interface_type_cellular);
            
            if (usesWiFi && usesCellular) {
                status = NetworkStatusWiFiCellular;
            } else if (usesWiFi) {
                status = NetworkStatusWiFi;
            } else if (usesCellular) {
                status = NetworkStatusCellular;
            }
        }

        callback(status); // 回调网络状态
    });

    nw_path_monitor_start(_monitor);
    //兼容海外版,首次没有回调。
    if ([[PSCRequestManager sharedInstance] isNetworkReachable]) {
        callback(NetworkStatusWiFiCellular); // 回调网络状态
    }
}