美文网首页
检测网络状态

检测网络状态

作者: 半江瑟瑟 | 来源:发表于2016-09-08 14:35 被阅读99次

vc中使用 viewDidLoad---dealloc willAppear --- willDidDisappear
#pragma mark - 苹果提供的方法
/// 当检测到网络断开时会间隔15s再次检测,如果还是断开则弹窗提醒,防止过于频繁操作
- (void)appleReachabilityTest {
/// Reachability使用了通知,当网络状态发生变化时发送通知kReachabilityChangedNotification
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(appReachabilityChanged:)
name:kReachabilityChangedNotification
object:nil];

// 被通知函数运行的线程应该由startNotifier函数执行的线程决定
typeof(self) weakSelf = self;
dispatch_async(dispatch_get_global_queue(0, 0), ^{
    NSString *remoteHostName = @"www.bing.com";
    /**
     *  有可能有问题这个带host的实例化方法--判断不准确--可以用reachabilityForInternetConnection来替代
     */
    weakSelf.hostReachability = [Reachability reachabilityWithHostName:remoteHostName];
    [weakSelf.hostReachability startNotifier];
    
    weakSelf.routerReachability = [Reachability reachabilityForInternetConnection];
    [weakSelf.routerReachability startNotifier];
    // 开启当前线程消息循环
    [[NSRunLoop currentRunLoop] run];
});
}

/// 当网络状态发生变化时调用
 - (void)appReachabilityChanged:(NSNotification *)notification{
Reachability *reach = [notification object];
if([reach isKindOfClass:[Reachability class]]){
    NetworkStatus status = [reach currentReachabilityStatus];
    // 两种检测:路由与服务器是否可达  三种状态:手机流量联网、WiFi联网、没有联网
    if (reach == self.routerReachability) {
        if (status == NotReachable) {
//                NSLog(@"routerReachability NotReachable");
            // 15秒后再次检测
            [self performSelector:@selector(appReachabilityChangedConfirm) withObject:nil afterDelay:15];
        } else if (status == ReachableViaWiFi) {
            NSLog(@"routerReachability ReachableViaWiFi--%@",[NSThread currentThread]);
        } else if (status == ReachableViaWWAN) {
            NSLog(@"routerReachability ReachableViaWWAN");
        } else if (status == kReachableVia4G){
            NSLog(@"routerReachability ReachableVia4G");
        } else if(status == kReachableVia3G){
            NSLog(@"routerReachability ReachableVia3G");
        }else if(status == kReachableVia2G){
            NSLog(@"routerReachability ReachableVia2G");
        }
    }
    if (reach == self.hostReachability) {
        if (status == NotReachable) {
            NSLog(@"hostReachability failed");
        }else if (status == ReachableViaWiFi) {
            NSLog(@"hostReachability ReachableViaWiFi--%@",[NSThread currentThread]);
        } else if (status == ReachableViaWWAN) {
            NSLog(@"hostReachability ReachableViaWWAN");
        } else if (status == kReachableVia4G){
            NSLog(@"hostReachability ReachableVia4G");
        } else if(status == kReachableVia3G){
            NSLog(@"hostReachability ReachableVia3G");
        }else if(status == kReachableVia2G){
            NSLog(@"hostReachability ReachableVia2G");
        }
    }
}
}
/// 再次检测网络,如果还是断开,则视为网络已经断开
- (void)appReachabilityChangedConfirm {
if([self.routerReachability isKindOfClass:[Reachability class]]){
    if ([self.routerReachability currentReachabilityStatus] == NotReachable) {
        dispatch_async(dispatch_get_main_queue(), ^{
            UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"网络中断" message:@"请检查网络" preferredStyle:UIAlertControllerStyleAlert];
            UIAlertAction *cancelBtn = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:nil];
            UIAlertAction *okBtn = [UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:nil];
            [alert addAction:cancelBtn];
            [alert addAction:okBtn];
            [self presentViewController:alert animated:YES completion:nil];
        });
    }
}
}

修改源文件增加检测2G/3G/4G功能
.h修改枚举值
typedef enum : NSInteger { NotReachable = 0, ReachableViaWiFi, ReachableViaWWAN, kReachableVia4G, kReachableVia2G, kReachableVia3G } NetworkStatus;

.m
增加头文件
#import <UIKit/UIDevice.h>
#import <CoreTelephony/CTTelephonyNetworkInfo.h>

/Radio Access Technology values/

Paste_Image.png

然后修改此方法
- (NetworkStatus)networkStatusForFlags:(SCNetworkReachabilityFlags)flags
{
PrintReachabilityFlags(flags, "networkStatusForFlags");
if ((flags & kSCNetworkReachabilityFlagsReachable) == 0)
{
// The target host is not reachable.
return NotReachable;
}

NetworkStatus returnValue = NotReachable;

if ((flags & kSCNetworkReachabilityFlagsConnectionRequired) == 0)
{
    /*
     If the target host is reachable and no connection is required then we'll assume (for now) that you're on Wi-Fi...
     */
    returnValue = ReachableViaWiFi;
}

if ((((flags & kSCNetworkReachabilityFlagsConnectionOnDemand ) != 0) ||
     (flags & kSCNetworkReachabilityFlagsConnectionOnTraffic) != 0))
{
    /*
     ... and the connection is on-demand (or on-traffic) if the calling application is using the CFSocketStream or higher APIs...
     */
    
    if ((flags & kSCNetworkReachabilityFlagsInterventionRequired) == 0)
    {
        /*
         ... and no [user] intervention is needed...
         */
        returnValue = ReachableViaWiFi;
    }
}
//
// if ((flags & kSCNetworkReachabilityFlagsIsWWAN) == kSCNetworkReachabilityFlagsIsWWAN)
// {
//  /*
//         ... but WWAN connections are OK if the calling application is using the CFNetwork APIs.
//         */
//  returnValue = ReachableViaWWAN;
// }

if ((flags & kSCNetworkReachabilityFlagsIsWWAN) == kSCNetworkReachabilityFlagsIsWWAN)
{
    /*
     ... but WWAN connections are OK if the calling application is using the CFNetwork APIs.
     */
    returnValue = ReachableViaWWAN;
    if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0) {
        CTTelephonyNetworkInfo *phonyNetwork = [[CTTelephonyNetworkInfo alloc] init];
        NSString *currentStr = phonyNetwork.currentRadioAccessTechnology;
        if (currentStr) {
            if ([currentStr isEqualToString:CTRadioAccessTechnologyLTE]) {
                returnValue = kReachableVia4G;
            }else if ([currentStr isEqualToString:CTRadioAccessTechnologyGPRS]|| [currentStr isEqualToString:CTRadioAccessTechnologyEdge]){
                returnValue = kReachableVia2G;
            }else{
                returnValue = kReachableVia3G;
            }
        }
    }else{
        if ((flags & kSCNetworkReachabilityFlagsTransientConnection) == kSCNetworkReachabilityFlagsTransientConnection) {
            
            returnValue = kReachableVia3G;
            
            if((flags & kSCNetworkReachabilityFlagsConnectionRequired) == kSCNetworkReachabilityFlagsConnectionRequired) {
                returnValue = kReachableVia2G;
            }
        }
    }
}

return returnValue;
}

<发现有时候通知会发出2次;有时候通知发出1次?why!>
我觉得应该发出2次才对啊 startNotifier方法调用了2次啊!

Paste_Image.png Paste_Image.png Paste_Image.png

demo地址:
https://github.com/jiangweike/networkStatus
参考文章
https://blog.6ag.cn/1310.html
http://xiongzenghuidegithub.github.io/blog/2013/12/30/reachabilityyuan-ma-xue-xi/
http://blog.csdn.net/Axing1991/article/details/46649939
http://www.jianshu.com/p/d95c8879d8d5
http://www.cnblogs.com/mddblog/p/5304346.html
http://www.cnblogs.com/scut-linmaojiang/p/iOS-Reachability.html
https://github.com/mddios/NetworkStauts
http://blog.csdn.net/applelg/article/details/47660577
http://www.ithao123.cn/content-2198058.html
https://www.mgenware.com/blog/?p=487
http://www.jianshu.com/p/1b0901d0902b

相关文章

网友评论

      本文标题:检测网络状态

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