Reachability实时准确监听网络状态

/ 0

公司项目需要精确传递2g、3g、4g、WiFi网络状态参数,所以就想到了苹果的Reachability。但今天被Reachability给坑了,初始化的时候使用 +reachabilityWithHostName:@"https://www.baidu.com"方法,结果每次检测到的结果都是无网络。所以记下来这个坑,分享给大家。

实时检测网络状态我们一般都是放在AppDelegate,所以先在AppDelegate导入头文件 Reachability.h并在AppDelegate头文件定义一个属性hostReach。

#import <UIKit/UIKit.h>
#import "Reachability.h"

@interface AppDelegate : UIResponder <UIApplicationDelegate>

@property (strong, nonatomic) UIWindow *window;
@property (strong, nonatomic) Reachability *hostReach;
@end

在.m文件中实现检测方法

// 实时监测网络情况
- (void)setupReachability {
    // 发送监听通知,监听网络状态的改变,注意这里初始化Reachability用到的类方法
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(reachabilityChanged:)
                                                 name: kReachabilityChangedNotification
                                               object: nil];
    self.hostReach = [Reachability reachabilityForInternetConnection];
    [self.hostReach startNotifier];
}

// 网络状态改变的通知方法
- (void)reachabilityChanged:(NSNotification *)notification {
    Reachability *curReach = [notification object];
    NSParameterAssert([curReach isKindOfClass:[Reachability class]]);
    
    switch ([curReach currentReachabilityStatus]) {
        case NotReachable: {
            WSLog(@"无网络");
        }
            break;
            
        case ReachableViaWiFi:
            WSLog(@"WiFi");
            break;
            
        case kReachableVia2G:
            WSLog(@"2G");
            break;
            
        case kReachableVia3G:
            WSLog(@"3G");
            break;
            
        case kReachableVia4G:
            WSLog(@"4G");
            break;
    }
}

然后在程序启动就开启监听,这样我们就能够监听到网络状态的实时改变了。

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

    [self setupReachability]; // 网络状态监听

    return YES;
}

当然,我们使用的时候一般并不只是为了知道网络状态改变,而是要根据网络状态做一些事件,这样我将监听封装在项目的网络工具类中。

/**
 *  获取网络状态
 *
 *  @return 返回 0未知 1WIFI 22G 33G 44G
 */
- (NSInteger)getCurrentReachability {

    AppDelegate * appDelegate = (AppDelegate *)[UIApplication sharedApplication].delegate;
    NSInteger status;
    
    switch (appDelegate.hostReach.currentReachabilityStatus) {
        case NotReachable:
            status = 0; // 无网络连接
            break;
            
        case ReachableViaWiFi:
            status = 1; // WiFi
            break;
            
        case kReachableVia2G:
            status = 2; // 2G
            break;
            
        case kReachableVia3G:
            status = 3; // 3G
            break;
            
        case kReachableVia4G:
            status = 4; // 4G
            break;
    }
    
    return status;
}

我们在使用的时候直接调用网络工具类的 -getCurrentReachability方法来获取当前网络状态,再做一些针对性的操作。