美文网首页
iOS网络状态检测-2020-08-27-周四

iOS网络状态检测-2020-08-27-周四

作者: 勇往直前888 | 来源:发表于2020-09-03 15:57 被阅读0次

    网络是APP不可缺少的一环,检测网络是否通也是一个现实的需求。目前所知,检测网络状态有三种方法。

    方法1:苹果给的demo

    这其实是一件比较奇怪的事情。检测网络状态是一个现实需求,照理说,苹果应该提供几个系统API。可是,偏偏没有,反而煞有介事地写了一个demo,并且还给了一个下载链接。reachability下载链接

    image.png

    真正有用的也就是一个.h .m文件,直接拖入工程,直接使用就可以了。

    image.png
    • 对象创建方法
    image.png
    • 监控开关
    image.png
    • 获取网络状态网络
    typedef enum : NSInteger {
        NotReachable = 0,
        ReachableViaWiFi,
        ReachableViaWWAN
    } NetworkStatus;
    
    - (NetworkStatus)currentReachabilityStatus;
    

    从字面状态就能知道什么意思。2G、3G、还是4G是不能区分的。

    • 监控网络变化

    如果网络发生变化,比如从WiFi变为无网络,是通过通知的方式实现的。在下载的demo里面有样例。

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(reachabilityChanged:) name:kReachabilityChangedNotification object:nil];
    
    /*!
     * Called by Reachability whenever status changes.
     */
    - (void) reachabilityChanged:(NSNotification *)note {
        Reachability* curReach = [note object];
        NSParameterAssert([curReach isKindOfClass:[Reachability class]]);
        NSString *message = @"当前网络状态:";
        NetworkStatus status = [reachability currentReachabilityStatus];
        switch (status) {
            case NotReachable:
                message = [message stringByAppendingString:@"无网络"];
                break;
            case ReachableViaWiFi:
                message = [message stringByAppendingString:@"WiFi"];
                break;
            case ReachableViaWWAN:
                message = [message stringByAppendingString:@"移动数据"];
                break;
            default:
                break;
        }
       // ... ...
    }
    

    选择建议:毕竟是官方的,可以选择使用,用起来也很简洁。

    Reachability 实时监控网络状态

    AFNetworking

    在iOS开发领域,目前AFNetworking基本上已经成为了事实上的标准。检测网络状态这个功能也是有的。类的名字叫AFNetworkReachabilityManager

    image.png
    • 对象创建方式:
    ///---------------------
    /// @name Initialization
    ///---------------------
    
    /**
     Returns the shared network reachability manager.
     */
    + (instancetype)sharedManager;
    
    /**
     Creates and returns a network reachability manager with the default socket address.
     
     @return An initialized network reachability manager, actively monitoring the default socket address.
     */
    + (instancetype)manager;
    
    /**
     Creates and returns a network reachability manager for the specified domain.
    
     @param domain The domain used to evaluate network reachability.
    
     @return An initialized network reachability manager, actively monitoring the specified domain.
     */
    + (instancetype)managerForDomain:(NSString *)domain;
    
    /**
     Creates and returns a network reachability manager for the socket address.
    
     @param address The socket address (`sockaddr_in6`) used to evaluate network reachability.
    
     @return An initialized network reachability manager, actively monitoring the specified socket address.
     */
    + (instancetype)managerForAddress:(const void *)address;
    
    /**
     Initializes an instance of a network reachability manager from the specified reachability object.
    
     @param reachability The reachability object to monitor.
    
     @return An initialized network reachability manager, actively monitoring the specified reachability.
     */
    - (instancetype)initWithReachability:(SCNetworkReachabilityRef)reachability NS_DESIGNATED_INITIALIZER;
    
    /**
     *  Unavailable initializer
     */
    + (instancetype)new NS_UNAVAILABLE;
    
    /**
     *  Unavailable initializer
     */
    - (instancetype)init NS_UNAVAILABLE;
    

    可以看出,非常全面。通过前面分析,一般情况,我们最关心的是后台服务器是否通,所以,大多数情况下,可以使用下面这个:

    /**
     Creates and returns a network reachability manager for the specified domain.
    
     @param domain The domain used to evaluate network reachability.
    
     @return An initialized network reachability manager, actively monitoring the specified domain.
     */
    + (instancetype)managerForDomain:(NSString *)domain;
    
    • 监控开关也是有的
    ///--------------------------------------------------
    /// @name Starting & Stopping Reachability Monitoring
    ///--------------------------------------------------
    
    /**
     Starts monitoring for changes in network reachability status.
     */
    - (void)startMonitoring;
    
    /**
     Stops monitoring for changes in network reachability status.
     */
    - (void)stopMonitoring;
    
    • 获取网络状态网络

    网络状态以属性的方式给出。

    typedef NS_ENUM(NSInteger, AFNetworkReachabilityStatus) {
        AFNetworkReachabilityStatusUnknown          = -1,
        AFNetworkReachabilityStatusNotReachable     = 0,
        AFNetworkReachabilityStatusReachableViaWWAN = 1,
        AFNetworkReachabilityStatusReachableViaWiFi = 2,
    };
    
    /**
     The current network reachability status.
     */
    @property (readonly, nonatomic, assign) AFNetworkReachabilityStatus networkReachabilityStatus;
    
    • 监控网络状态变化

    可以通过block的方式来做,比较方便,不过需要注意引用循环的问题。

            self.manage = [AFNetworkReachabilityManager managerForDomain:hostName];
            __weak __typeof__(self) weakSelf = self;
            [self.manage setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) {
                __strong __typeof__(self) strongSelf = weakSelf;
                [strongSelf showAFNetworkingMessage:status];
            }];
            [self.manage startMonitoring];
    
    • 网络状态描述

    网络状态是一个枚举值,一般情况,可以自己定义网络状态描述的语言,比如“无网络”、“WiFi网络” ... ...等之类的。
    这里提供了一个将枚举值转换为字符串的方法,提供一些网络状态的描述

    /**
     Returns a localized string representation of the current network reachability status.
     */
    - (NSString *)localizedNetworkReachabilityStatusString;
    

    选择建议:既然网络库用了AFNetworking,网络状态检查现成有的,用这个最方便。

    第三方库RealReachability

    模仿苹果官方的demo,有人写了一个第三方库,有需求的可以用一下。

    iOS下的实际网络连接状态检测

    RealReachability

    • 对象创建方式

    只提供了单例方法,并且还给了一个方便使用的宏。并且制定的域名使用属性的方式指定。

    #define GLobalRealReachability [RealReachability sharedInstance]
    
    + (instancetype)sharedInstance;
    
    /// Please make sure this host is available for pinging! default host:www.apple.com
    @property (nonatomic, copy) NSString *hostForPing;
    
    @property (nonatomic, copy) NSString *hostForCheck;
    
    • 监控开关也是有的
    - (void)startNotifier;
    
    - (void)stopNotifier;
    
    • 网络状态多了移动网络状态,就是2G、3G、4G之类的区分,功能增强了。
    typedef NS_ENUM(NSInteger, ReachabilityStatus) {
        ///Direct match with Apple networkStatus, just a force type convert.
        RealStatusUnknown = -1,
        RealStatusNotReachable = 0,
        RealStatusViaWWAN = 1,
        RealStatusViaWiFi = 2
    };
    
    typedef NS_ENUM(NSInteger, WWANAccessType) {
        WWANTypeUnknown = -1, /// maybe iOS6
        WWANType4G = 0,
        WWANType3G = 1,
        WWANType2G = 3
    };
    
    /**
     *  Return current reachability immediately.
     *
     *  @return see enum LocalConnectionStatus
     */
    - (ReachabilityStatus)currentReachabilityStatus;
    
    /**
     *  Return current WWAN type immediately.
     *
     *  @return unknown/4g/3g/2g.
     *
     *  This method can be used to improve app's further network performance
     *  (different strategies for different WWAN types).
     */
    - (WWANAccessType)currentWWANtype;
    

    还可以看状态变化前的网络状态,还有block形式的异步网络状态:

    /**
     *  To get real reachability we need to do async request,
     *  then we use the block blow for invoker to handle business request(need real reachability).
     *  Now we have introduced a double check to make our result more reliable.
     *
     *  @param asyncHandler async request handler, return in 5 seconds(max limit).
     *  The limit time may be adjusted later for better experience.
     */
    - (void)reachabilityWithBlock:(void (^)(ReachabilityStatus status))asyncHandler;
    
    /**
     *  Return previous reachability status.
     *
     *  @return see enum LocalConnectionStatus
     */
    - (ReachabilityStatus)previousReachabilityStatus;
    
    • 检查是否是VPN
    /**
     *  Sometimes people use VPN on the device.
     *  In this situation we need to ignore the ping error.
     *  (VPN usually do not support ICMP.)
     *
     *  @return current VPN status: YES->ON, NO->OFF.
     *
     *  This method can be used to improve app's further network performance
     *  (different strategies for different WWAN types).
     */
    - (BOOL)isVPNOn;
    
    • 监控网络状态变化,这个也是通过通知的形式给出的
    ///This notification was called only when reachability really changed;
    ///We use FSM to promise this for you;
    ///We post self to this notification, then you can invoke currentReachabilityStatus method to fetch current status.
    extern NSString *const kRealReachabilityChangedNotification;
    
    extern NSString *const kRRVPNStatusChangedNotification;
    

    选择建议:使用方法基本上和苹果官方提供的是一样的,特色是增加了VPN检查,移动网络类型区分等功能。有这方面需求的可以考虑使用。

    Demo地址

    https://gitee.com/zhangxusong888/ObjectCDemo/tree/master/ReachabilityDemo

    相关文章

      网友评论

          本文标题:iOS网络状态检测-2020-08-27-周四

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