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

2020-09-03  本文已影响0人  勇往直前888

网络是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;
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;
/**
 *  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

上一篇下一篇

猜你喜欢

热点阅读