使用 Reachability 获取网络状态
Reachability
source https://developer.apple.com/library/ios/samplecode/Reachability/Introduction/Intro.html
reachability 为苹果官方demo提供的一个检测网络状态的代码,下载源码后本人对其进行了修改,修改后源码:
reachability.h + reachability.m
#import <Foundation/Foundation.h>
#import <SystemConfiguration/SystemConfiguration.h>
#import <netinet/in.h> typedef enum : NSInteger {
NotReachable = ,
ReachableViaWiFi,
ReachableViaWWAN
} NetworkStatus; extern NSString *kReachabilityChangedNotification; @interface Reachability : NSObject /*!
* Use to check the reachability of a given host name.
*/
+ (instancetype)reachabilityWithHostName:(NSString *)hostName; /*!
* Use to check the reachability of a given IP address.
*/
+ (instancetype)reachabilityWithAddress:(const struct sockaddr_in *)hostAddress; /*!
* Checks whether the default route is available. Should be used by applications that do not connect to a particular host.
*/
+ (instancetype)reachabilityForInternetConnection; /*!
* Checks whether a local WiFi connection is available.
*/
+ (instancetype)reachabilityForLocalWiFi; /*!
* Start listening for reachability notifications on the current run loop.
*/
- (BOOL)startNotifier;
- (void)stopNotifier; - (NetworkStatus)currentReachabilityStatus; /*!
* WWAN may be available, but not active until a connection has been established. WiFi may require a connection for VPN on Demand.
*/
- (BOOL)connectionRequired; /*!
* 测试是否能连接网
*/
+ (NetworkStatus)isExistNetwork; @end
#import <arpa/inet.h>
#import <ifaddrs.h>
#import <netdb.h>
#import <sys/socket.h> #import <CoreFoundation/CoreFoundation.h> #import "Reachability.h" NSString *kReachabilityChangedNotification = @"kNetworkReachabilityChangedNotification"; #pragma mark - Supporting functions #define kShouldPrintReachabilityFlags 1 static void PrintReachabilityFlags(SCNetworkReachabilityFlags flags, const char* comment)
{
#if kShouldPrintReachabilityFlags NSLog(@"Reachability Flag Status: %c%c %c%c%c%c%c%c%c %s\n",
(flags & kSCNetworkReachabilityFlagsIsWWAN) ? 'W' : '-',
(flags & kSCNetworkReachabilityFlagsReachable) ? 'R' : '-', (flags & kSCNetworkReachabilityFlagsTransientConnection) ? 't' : '-',
(flags & kSCNetworkReachabilityFlagsConnectionRequired) ? 'c' : '-',
(flags & kSCNetworkReachabilityFlagsConnectionOnTraffic) ? 'C' : '-',
(flags & kSCNetworkReachabilityFlagsInterventionRequired) ? 'i' : '-',
(flags & kSCNetworkReachabilityFlagsConnectionOnDemand) ? 'D' : '-',
(flags & kSCNetworkReachabilityFlagsIsLocalAddress) ? 'l' : '-',
(flags & kSCNetworkReachabilityFlagsIsDirect) ? 'd' : '-',
comment
);
#endif
} static void ReachabilityCallback(SCNetworkReachabilityRef target, SCNetworkReachabilityFlags flags, void* info)
{
#pragma unused (target, flags)
NSCAssert(info != NULL, @"info was NULL in ReachabilityCallback");
NSCAssert([(__bridge NSObject*) info isKindOfClass: [Reachability class]], @"info was wrong class in ReachabilityCallback"); Reachability* noteObject = (__bridge Reachability *)info;
// Post a notification to notify the client that the network reachability changed.
[[NSNotificationCenter defaultCenter] postNotificationName: kReachabilityChangedNotification object: noteObject];
} #pragma mark - Reachability implementation @implementation Reachability
{
BOOL _alwaysReturnLocalWiFiStatus; //default is NO
SCNetworkReachabilityRef _reachabilityRef;
} + (instancetype)reachabilityWithHostName:(NSString *)hostName
{
Reachability* returnValue = NULL;
SCNetworkReachabilityRef reachability = SCNetworkReachabilityCreateWithName(NULL, [hostName UTF8String]);
if (reachability != NULL)
{
returnValue= [[self alloc] init];
if (returnValue != NULL)
{
returnValue->_reachabilityRef = reachability;
returnValue->_alwaysReturnLocalWiFiStatus = NO;
}
}
return returnValue;
} + (instancetype)reachabilityWithAddress:(const struct sockaddr_in *)hostAddress
{
SCNetworkReachabilityRef reachability = SCNetworkReachabilityCreateWithAddress(kCFAllocatorDefault, (const struct sockaddr *)hostAddress); Reachability* returnValue = NULL; if (reachability != NULL)
{
returnValue = [[self alloc] init];
if (returnValue != NULL)
{
returnValue->_reachabilityRef = reachability;
returnValue->_alwaysReturnLocalWiFiStatus = NO;
}
}
return returnValue;
} + (instancetype)reachabilityForInternetConnection
{
struct sockaddr_in zeroAddress;
bzero(&zeroAddress, sizeof(zeroAddress));
zeroAddress.sin_len = sizeof(zeroAddress);
zeroAddress.sin_family = AF_INET; return [self reachabilityWithAddress:&zeroAddress];
} + (instancetype)reachabilityForLocalWiFi
{
struct sockaddr_in localWifiAddress;
bzero(&localWifiAddress, sizeof(localWifiAddress));
localWifiAddress.sin_len = sizeof(localWifiAddress);
localWifiAddress.sin_family = AF_INET; // IN_LINKLOCALNETNUM is defined in <netinet/in.h> as 169.254.0.0.
localWifiAddress.sin_addr.s_addr = htonl(IN_LINKLOCALNETNUM); Reachability* returnValue = [self reachabilityWithAddress: &localWifiAddress];
if (returnValue != NULL)
{
returnValue->_alwaysReturnLocalWiFiStatus = YES;
} return returnValue;
} #pragma mark - Start and stop notifier - (BOOL)startNotifier
{
BOOL returnValue = NO;
SCNetworkReachabilityContext context = {, (__bridge void *)(self), NULL, NULL, NULL}; if (SCNetworkReachabilitySetCallback(_reachabilityRef, ReachabilityCallback, &context))
{
if (SCNetworkReachabilityScheduleWithRunLoop(_reachabilityRef, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode))
{
returnValue = YES;
}
} return returnValue;
} - (void)stopNotifier
{
if (_reachabilityRef != NULL)
{
SCNetworkReachabilityUnscheduleFromRunLoop(_reachabilityRef, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
}
} - (void)dealloc
{
[self stopNotifier];
if (_reachabilityRef != NULL)
{
CFRelease(_reachabilityRef);
}
} #pragma mark - Network Flag Handling - (NetworkStatus)localWiFiStatusForFlags:(SCNetworkReachabilityFlags)flags
{
PrintReachabilityFlags(flags, "localWiFiStatusForFlags");
NetworkStatus returnValue = NotReachable; if ((flags & kSCNetworkReachabilityFlagsReachable) && (flags & kSCNetworkReachabilityFlagsIsDirect))
{
returnValue = ReachableViaWiFi;
} return returnValue;
} - (NetworkStatus)networkStatusForFlags:(SCNetworkReachabilityFlags)flags
{
PrintReachabilityFlags(flags, "networkStatusForFlags");
if ((flags & kSCNetworkReachabilityFlagsReachable) == )
{
// The target host is not reachable.
return NotReachable;
} NetworkStatus returnValue = NotReachable; if ((flags & kSCNetworkReachabilityFlagsConnectionRequired) == )
{
/*
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 ) != ) ||
(flags & kSCNetworkReachabilityFlagsConnectionOnTraffic) != ))
{
/*
... and the connection is on-demand (or on-traffic) if the calling application is using the CFSocketStream or higher APIs...
*/ if ((flags & kSCNetworkReachabilityFlagsInterventionRequired) == )
{
/*
... 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;
} return returnValue;
} - (BOOL)connectionRequired
{
NSAssert(_reachabilityRef != NULL, @"connectionRequired called with NULL reachabilityRef");
SCNetworkReachabilityFlags flags; if (SCNetworkReachabilityGetFlags(_reachabilityRef, &flags))
{
return (flags & kSCNetworkReachabilityFlagsConnectionRequired);
} return NO;
} - (NetworkStatus)currentReachabilityStatus
{
NSAssert(_reachabilityRef != NULL, @"currentNetworkStatus called with NULL SCNetworkReachabilityRef");
NetworkStatus returnValue = NotReachable;
SCNetworkReachabilityFlags flags; if (SCNetworkReachabilityGetFlags(_reachabilityRef, &flags))
{
if (_alwaysReturnLocalWiFiStatus)
{
returnValue = [self localWiFiStatusForFlags:flags];
}
else
{
returnValue = [self networkStatusForFlags:flags];
}
} return returnValue;
} + (NetworkStatus)isExistNetwork
{
NetworkStatus isExistenceNetwork; //单例
static Reachability *reachability = nil; //服务器地址选择了百度
if (reachability == nil)
{
reachability = [Reachability reachabilityWithHostName:@"www.baidu.com"];
} switch([reachability currentReachabilityStatus]) {
case NotReachable:
isExistenceNetwork = NotReachable;
break;
case ReachableViaWWAN:
isExistenceNetwork = ReachableViaWWAN;
break;
case ReachableViaWiFi:
isExistenceNetwork = ReachableViaWiFi;
break;
} return isExistenceNetwork;
} @end
直接使用下面的代码来得到网络信息,是单例模式,无需担心浪费内存
[Reachability isExistNetwork];
其返回3个枚举值,判断一下即可,
NotReachable, ReachableViaWiFi, ReachableViaWWAN
使用通知来监听网络状态
1.定义属性(strong)
@property (nonatomic, strong) Reachability *hostReachability;
@property (nonatomic, strong) Reachability *internetReachability;
@property (nonatomic, strong) Reachability *wifiReachability;
2.指定监听的方法
- (void) reachabilityChanged:(NSNotification *)note
{
Reachability *tmp = [note object];
NSLog(@"%d", [tmp currentReachabilityStatus]);
}
3.初始化以及监听
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(reachabilityChanged:)
name:kReachabilityChangedNotification
object:nil];
NSString *remoteHostName = @"www.baidu.com";
_hostReachability = [Reachability reachabilityWithHostName:remoteHostName];
[_hostReachability startNotifier];
_internetReachability = [Reachability reachabilityForInternetConnection];
[_internetReachability startNotifier];
_wifiReachability = [Reachability reachabilityForLocalWiFi];
[_wifiReachability startNotifier];
使用 Reachability 获取网络状态的更多相关文章
- iOS 获取网络状态
在iOS开发者,获取网络状态比较常用 -(NSString *)getNetWorkStates{ UIApplication *app = [UIApplication sharedApplicat ...
- android开发获取网络状态,wifi,wap,2g,3g.工具类(一)
android开发获取网络状态整理: package com.gzcivil.utils; import android.content.Context; import android.net.Con ...
- Android获取网络状态
Android获取网络状态 学习自 https://developer.android.google.cn/reference/android/net/ConnectivityManager http ...
- 微信小程序 --- 获取网络状态
获取网络状态:wx.getNetworkType btnclick:function(){ wx.getNetworkType({ success:function(res){ console.log ...
- React Native之Fetch简单封装、获取网络状态
1.Fetch的使用 fetch的使用非常简单,只需传入请求的url fetch('https://facebook.github.io/react-native/movies.json'); 当然是 ...
- C#获取网络状态
/// <summary> /// 获取网络状态 /// </summary> /// <param name="ip">目标IP地址</ ...
- [React Native]获取网络状态
使用React Native,可以使用NetInfo API获取手机当前的各个网络状态. componentWillMount() { NetInfo.fetch().done((status)=&g ...
- iOS开发网络篇—Reachability检测网络状态
前言:当应用程序需要访问网络的时候,它首先应该检查设备的网络状态,确认设备的网络环境及连接情况,并针对这些情况提醒用户做出相应的处理.最好能监听设备的网络状态的改变,当设备网络状态连接.断开时,程序也 ...
- iOS网络4——Reachability检测网络状态
一.整体介绍 前面已经介绍了网络访问的NSURLSession.NSURLConnection,还有网页加载有关的webview,基本满足通常的网络相关的开发. 其实在网络开发中还有比较常用的就是网络 ...
随机推荐
- Java 常用的几个lambda表达式
Lambda表达式是Java 8一个非常重要的新特性.它像方法一样,利用很简单的语法来定义参数列表和方法体.目前Lambda表达式已经成为高级编程语言的标配,像Python,Swift,C#等都已经支 ...
- Ansible常见模块介绍
本节内容: ansible命令基础 常见模块举例 一.ansible命令基础 语法: ansible <host-pattern> [-f forks] [-m module_name] ...
- 【58沈剑架构系列】RPC-client异步收发核心细节?
第一章聊了[“为什么要进行服务化,服务化究竟解决什么问题”] 第二章聊了[“微服务的服务粒度选型”] 第三章聊了[“为什么说要搞定微服务架构,先搞定RPC框架?”] 上一章聊了[“微服务架构之RPC- ...
- 【LOJ】#2041. 「SHOI2015」聚变反应炉
题解 这显然是一道题拆成两道 然后我胡乱分析了一波,决定第一题就用点度贪心(反正散播的能量肯定能被使用),然后过了 第二题开始mengbier 设\(f_u\)表示第u个点在父亲发动之后才发动的最小价 ...
- hive将数据导致本地磁盘
hive -e "select * from wyp" >> local/wyp.txt 其中我更喜欢弄好临时表,然后交互式查询时让相关人员自己去按逻辑处理数据,最 ...
- 正规表达式 转 NFA C++
今天来为大家分享一个编译原理中用正规表达式转NFA的小程序 正规表达式就是类似正则一样的式子,例如:(a|b)*abb,最后应该转化为: 大致的处理流程为: 例子中的表达式:(a|b)*abb,|和* ...
- (四)静态断言(上),assert,NDEBUG, 以及通过宏定义处理文件包含关系
一.断言:运行时与预处理时 断言(assertion)是一种编程常用的手段.想必大家都见过 assert 吧.今天我们就来了解一下它. 通常情况下,断言就是将一个返回值总是需要为真的判别式放在语句中, ...
- Sublime Text 下的Install Package安装方法
废话不多说.... 如果你是Sublime Text3用户,按下Ctrl+~呼出控制台,输入以下代码 import urllib.request,os,hashlib; h = '7183a2d3e9 ...
- BZOJ.5329.[SDOI2018]战略游戏(圆方树 虚树)
题目链接 显然先建圆方树,方点权值为0圆点权值为1,两点间的答案就是路径权值和减去起点终点. 对于询问,显然可以建虚树.但是只需要计算两关键点间路径权值,所以不需要建出虚树.统计DFS序相邻的两关键点 ...
- 洛谷.4383.[八省联考2018]林克卡特树lct(树形DP 带权二分)
题目链接 \(Description\) 给定一棵边带权的树.求删掉K条边.再连上K条权为0的边后,新树的最大直径. \(n,K\leq3\times10^5\). \(Solution\) 题目可以 ...