监听网络状态的改变
来源:互联网 发布:excel数据提取工具 编辑:程序博客网 时间:2024/05/19 00:53
监听网络状态
//这是一个已经封装好的监听网络状态的文件,直接拖进来使用就行了//Reachability.h#import <Foundation/Foundation.h>#import <SystemConfiguration/SystemConfiguration.h>#import <netinet/in.h>typedef enum : NSInteger { NotReachable = 0, // 没有连接 ReachableViaWiFi, // 通过 WiFi 连接 ReachableViaWWAN // 通过 2G/3G/4G 连接} NetworkStatus;extern NSString *kReachabilityChangedNotification;@interface Reachability : NSObject/*! 检测能否连接到指定的主机 * Use to check the reachability of a given host name. */+ (instancetype)reachabilityWithHostName:(NSString *)hostName;/*! 检测能否连接到指定的 IP 地址 * 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;/*! 检查本地 wifi 是否可用 * Checks whether a local WiFi connection is available. */+ (instancetype)reachabilityForLocalWiFi;/*! 开始在当前运行循环监听网络连接通知 * Start listening for reachability notifications on the current run loop. */- (BOOL)startNotifier;/** * 停止监听器 */- (void)stopNotifier;/** * 当前连接状态 * * @return 网络状态 */- (NetworkStatus)currentReachabilityStatus;/*! 是否需要连接 WWAN 在连接建立之前不能使用 Wi-Fi 通过 VPN 连接 * WWAN may be available, but not active until a connection has been established. WiFi may require a connection for VPN on Demand. */- (BOOL)connectionRequired;@end
//Reachability.m#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 1static 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 = {0, (__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) == 0) { // The target host is not reachable. return NotReachable; } NetworkStatus returnValue = NotReachable; if ((flags & kSCNetworkReachabilityFlagsConnectionRequired) == 0) { /* 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 ) != 0) || (flags & kSCNetworkReachabilityFlagsConnectionOnTraffic) != 0)) { /* ... and the connection is on-demand (or on-traffic) if the calling application is using the CFSocketStream or higher APIs... */ if ((flags & kSCNetworkReachabilityFlagsInterventionRequired) == 0) { /* ... 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;}@end
- 主控制器文件
//ViewController.h#import <UIKit/UIKit.h>@interface ViewController : UIViewController@end
//ViewController.m#import "ViewController.h"#import "Reachability.h"@interface ViewController ()@property (nonatomic, strong) Reachability *reachablityManager;@end@implementation ViewController- (void)dealloc { // 移除通知 [[NSNotificationCenter defaultCenter] removeObserver:self]; // 移除监听网络状态 [self.reachablityManager stopNotifier];}- (void)viewDidLoad { [super viewDidLoad]; // 监听网络状态通知 [[NSNotificationCenter defaultCenter ] addObserver:self selector:@selector(networkStatusChanged) name:kReachabilityChangedNotification object:nil]; // 开始监听(这里可以理解为让RunLoop来监听网络状态,当监听的网络状态改变时,会对外发出kReachabilityChangedNotification通知) [self.reachablityManager startNotifier];}//手动点击来刷新网络状态(可不要)- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event { [self networkStatusChanged];}/** * 网络状态改变的回调方法 */- (void)networkStatusChanged { // 获得当前的网络状态 NetworkStatus status = [self.reachablityManager currentReachabilityStatus]; switch (status) { case NotReachable: NSLog(@"木有连接,没有网络"); break; case ReachableViaWiFi: NSLog(@"wifi,不用钱,尽管用"); break; case ReachableViaWWAN: NSLog(@"3G/4G,要钱,土豪随意"); break; }}- (Reachability *)reachablityManager { if (_reachablityManager == nil) { // 在实际开发中,填写公司的服务器域名 _reachablityManager = [Reachability reachabilityWithHostName:@"baidu.com"]; } return _reachablityManager;}@end
0 0
- 监听网络状态的改变
- 监听网络状态的改变
- 监听网络状态改变
- android 监听网络连接状态的改变
- android 监听网络连接状态的改变
- android 监听网络连接状态的改变
- android 监听网络连接状态的改变
- android 监听网络连接状态的改变
- android 监听网络连接状态的改变
- android 监听网络连接状态的改变
- android 监听网络连接状态的改变
- android监听手机网络连接状态改变的后台服务
- Android学习之 监听网络连接状态的改变
- Andorid 网络状态改变监听不到问题的解决
- Android:使用Broadcast Receiver监听网络连接状态的改变
- 安卓监听网络状态改变
- Android的网络状态监听
- AFNetworking的网络状态监听
- 模拟器默认横屏
- 62. Unique Paths
- [IOS]socket发送消息长度计算
- Linux字符串操作函数
- 学习篇---FlowLayout的实现
- 监听网络状态的改变
- Android全屏和adjustResize的冲突解决
- emacs命令
- 古诗词的直译和韵译有什么区别?看看就知道了
- MySQL 高可用架构在业务层面细化分析研究
- View的点击事件分发机制
- QDateTime操作
- 后台长存的ios
- 北方国家金融公司公布第一季度业绩