iOS网络状态检测-2020-08-27-周四
网络是APP不可缺少的一环,检测网络是否通也是一个现实的需求。目前所知,检测网络状态有三种方法。
方法1:苹果给的demo
这其实是一件比较奇怪的事情。检测网络状态是一个现实需求,照理说,苹果应该提供几个系统API。可是,偏偏没有,反而煞有介事地写了一个demo,并且还给了一个下载链接。reachability下载链接
image.png真正有用的也就是一个.h .m文件,直接拖入工程,直接使用就可以了。
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;
}
// ... ...
}
选择建议:毕竟是官方的,可以选择使用,用起来也很简洁。
AFNetworking
在iOS开发领域,目前AFNetworking基本上已经成为了事实上的标准。检测网络状态这个功能也是有的。类的名字叫AFNetworkReachabilityManager
- 对象创建方式:
///---------------------
/// @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,有人写了一个第三方库,有需求的可以用一下。
- 对象创建方式
只提供了单例方法,并且还给了一个方便使用的宏。并且制定的域名使用属性的方式指定。
#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