美文网首页iOSiOS DeveloperiOS开发-网络
iOS 获取网络状态及信号强度(WiFi、蜂窝网络)

iOS 获取网络状态及信号强度(WiFi、蜂窝网络)

作者: 逗憨de逗 | 来源:发表于2017-09-05 14:12 被阅读528次

现在百度上搜索到的获取网络信号强度的blog比较纷杂。要么是用私有api;要么太旧,不能在新的操作系统上跑;要么就是得越狱。

我经历过从越狱到非越狱,从iOS7到现在的iOS10,各种版本,都有尝试。现将我的代码贴出来,希望能帮到大家。包括WiFi和蜂窝网络的信号都可以获取。
真机测试环境:iOS10.3.3 iOS9.1(无需越狱)

//检查当前是否连网

- (BOOL)whetherConnectedNetwork
{
    //创建零地址,0.0.0.0的地址表示查询本机的网络连接状态
    
    struct sockaddr_storage zeroAddress;//IP地址
    
    bzero(&zeroAddress, sizeof(zeroAddress));//将地址转换为0.0.0.0
    zeroAddress.ss_len = sizeof(zeroAddress);//地址长度
    zeroAddress.ss_family = AF_INET;//地址类型为UDP, TCP, etc.
    
    // Recover reachability flags
    SCNetworkReachabilityRef defaultRouteReachability = SCNetworkReachabilityCreateWithAddress(NULL, (struct sockaddr *)&zeroAddress);
    SCNetworkReachabilityFlags flags;
    
    //获得连接的标志
    BOOL didRetrieveFlags = SCNetworkReachabilityGetFlags(defaultRouteReachability, &flags);
    CFRelease(defaultRouteReachability);
    
    //如果不能获取连接标志,则不能连接网络,直接返回
    if (!didRetrieveFlags)
    {
        return NO;
    }
    //根据获得的连接标志进行判断
    
    BOOL isReachable = flags & kSCNetworkFlagsReachable;
    BOOL needsConnection = flags & kSCNetworkFlagsConnectionRequired;
    return (isReachable&&!needsConnection) ? YES : NO;
}

//获取网络状态

- (NSString *)getNetworkType {
    if (![self whetherConnectedNetwork]) return @"NONE";
    UIApplication *app = [UIApplication sharedApplication];
    NSArray *subviews = [[[app valueForKeyPath:@"statusBar"] valueForKeyPath:@"foregroundView"] subviews];
    NSString *type = @"NONE";
    for (id subview in subviews) {
        if ([subview isKindOfClass:NSClassFromString(@"UIStatusBarDataNetworkItemView")]) {
            int networkType = [[subview valueForKeyPath:@"dataNetworkType"] intValue];
            switch (networkType) {
                case 0:
                    type = @"NONE";
                    break;
                case 1:
                    type = @"2G";
                    break;
                case 2:
                    type = @"3G";
                    break;
                case 3:
                    type = @"4G";
                    break;
                case 5:
                    type = @"WIFI";
                    break;
            }
        }
    }
    return type;
}

//获取网络信号强度(dBm)

- (NSString *)getSignalStrength {
    if (![self whetherConnectedNetwork]) return @"";
    UIApplication *app = [UIApplication sharedApplication];
    NSArray *subviews = [[[app valueForKey:@"statusBar"] valueForKey:@"foregroundView"] subviews];
    NSString *dataNetworkItemView = nil;
    NSString *signalStrength = @"";
    for (id subview in subviews) {
        if([subview isKindOfClass:[NSClassFromString(@"UIStatusBarDataNetworkItemView") class]] && [[self getNetworkType] isEqualToString:@"WIFI"] && ![[self getNetworkType] isEqualToString:@"NONE"]) {
            dataNetworkItemView = subview;
            signalStrength = [NSString stringWithFormat:@"%@dBm",[dataNetworkItemView valueForKey:@"_wifiStrengthRaw"]];
            break;
        }
        if ([subview isKindOfClass:[NSClassFromString(@"UIStatusBarSignalStrengthItemView") class]] && ![[self getNetworkType] isEqualToString:@"WIFI"] && ![[self getNetworkType] isEqualToString:@"NONE"]) {
            dataNetworkItemView = subview;
            signalStrength = [NSString stringWithFormat:@"%@dBm",[dataNetworkItemView valueForKey:@"_signalStrengthRaw"]];
            break;
        }
    }
    return signalStrength;
}

//获取网络信号强度等级
WiFi是指


蜂窝网络信号是指



可以放在网络信号强度旁,用图片显示,比较直观

- (NSString *)getSignalStrengthBar {
    if (![self whetherConnectedNetwork]) return @"";
    UIApplication *app = [UIApplication sharedApplication];
    NSArray *subviews = [[[app valueForKey:@"statusBar"] valueForKey:@"foregroundView"] subviews];
    NSString *dataNetworkItemView = nil;
    NSString *signalStrengthBars = @"";
    for (id subview in subviews) {
        if([subview isKindOfClass:[NSClassFromString(@"UIStatusBarDataNetworkItemView") class]] && [[self getNetworkType] isEqualToString:@"WIFI"] && ![[self getNetworkType] isEqualToString:@"NONE"]) {
            dataNetworkItemView = subview;
            signalStrengthBars = [NSString stringWithFormat:@"0%@",[dataNetworkItemView valueForKey:@"_wifiStrengthBars"]];
            break;
        }
        if ([subview isKindOfClass:[NSClassFromString(@"UIStatusBarSignalStrengthItemView") class]] && ![[self getNetworkType] isEqualToString:@"WIFI"] && ![[self getNetworkType] isEqualToString:@"NONE"]) {
            dataNetworkItemView = subview;
            signalStrengthBars = [NSString stringWithFormat:@"1%@",[dataNetworkItemView valueForKey:@"_signalStrengthBars"]];
            break;
        }
    }
    return signalStrengthBars;
}

这里没有申请NetworkExtension框架的使用,也没办法对WiFi进行更进一步的操作,只是对信号强度的获取。毕竟你申请NetworkExtension框架的使用,是要问你为什么搞这个滴,没有合适的理由,也不好过。

使用的时候记得导入<SystemConfiguration/SystemConfiguration.h>,实时监测网络信号强度,放到NSTimer就好,时间间隔,建议1秒。

在这里扯个淡,记得当初在网络上查到可以通过遍历UIStatusBar获取WiFi信号强度,顿时觉得,蜂窝是不是也可以通过这个方式查到,一是因为翻墙Google了很多次相关资料,二是觉得老外干活儿比较规范,就用相关单词,一个单词一个单词的替换_wifiStrengthRaw变量中的wifi,结果还真弄出来了。

还有就是,前公司做的产品比较偏,后期都没有在AppStore上线,都是通过企业账号发布,或者在Cydia上发布越狱,所以不清楚这个可不可以上线AppStore。所以用这个可以上线的话,请留言告诉我,或者告诉大家。

应该是墙内全网首次发布,墙外不清楚,希望转发注明出处,毕竟第一次写blog,谢谢!

相关文章

网友评论

  • sarsama:NSArray *subviews = [[[app valueForKeyPath:@"statusBar"] valueForKeyPath:@"foregroundView"] subviews];
    我这个取到的是nil,真机测试
    逗憨de逗:是iPhone X吧!iPhone X目前没有去搞~~毕竟还没有普及11的越狱~~
  • 762683ff5d3d:可以通过appstore发布
  • 子豪_:信号强度好像是用_wifiStrengthBar和_signalStrengthBar表示
  • timelyRain:iPhone X 无法获取了
    timelyRain:@逗憨de逗 是可以获取到这个view,但是它的类型是UIView,无法根据它去获取网络状态
    逗憨de逗:应该是获取不到Bar了
    UIApplication *app = [UIApplication sharedApplication];
    //iPhone X兼容导航条获取
    NSArray *subviews = @[];
    if([[app valueForKeyPath:@"_statusBar"] isKindOfClass:NSClassFromString(@"UIStatusBar_Modern")]) {
    subviews = [[[[app valueForKeyPath:@"_statusBar"] valueForKeyPath:@"_statusBar"] valueForKeyPath:@"foregroundView"] subviews];
    } else {
    subviews = [[[app valueForKeyPath:@"_statusBar"] valueForKeyPath:@"foregroundView"] subviews];
    }
    这个网络状态是可以获取到的,但是信号强度没有试过,新公司并没有iPhone X的测试机,什么情况可以说一声。理论上应该没有问题。

本文标题:iOS 获取网络状态及信号强度(WiFi、蜂窝网络)

本文链接:https://www.haomeiwen.com/subject/fimujxtx.html