AFNetworking 3.0 源码解析之Reachability
来源:互联网 发布:淘宝销售宣传标语 编辑:程序博客网 时间:2024/06/06 16:47
AFNetworking 3.0 源码解析之Reachability
Reachability这部分主要负责网络的状态网络状态的监听。
首先介绍下使用方法。
这里介绍三种使用方法:
1)直接使用单利,调用
AFNetworkReachabilityManager *reachabilityManager = [AFNetworkReachabilityManager sharedManager]; [reachabilityManager startMonitoring]; [reachabilityManager setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) { NSLog(@"status %ld", (long)status); }];2)使用AFURLSessionManager的属性调用
AFHTTPSessionManager *sessionManager = [[AFHTTPSessionManager alloc] initWithBaseURL:[NSURL URLWithString:@"https://www.baidu.com"] sessionConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]]; sessionManager.responseSerializer = [AFHTTPResponseSerializer serializer]; [sessionManager.reachabilityManager startMonitoring]; [sessionManager.reachabilityManager setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) { NSLog(@"status %ld", (long)status); }];3)使用通知中心的模式,监听
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(reachabilityCallBack:) name:AFNetworkingReachabilityDidChangeNotification object:nil];- (void)reachabilityCallBack:(NSNotification *)sender { NSDictionary *userInfo = sender.userInfo; AFNetworkReachabilityStatus netStatus = [userInfo[@"AFNetworkingReachabilityNotificationStatusItem"] integerValue]; NSLog(@"netStatus %ld ", netStatus);}
使用方法还是比较简单的。
下面分析下源码。
1.初始化网络监听
+ (instancetype)sharedManager;+ (instancetype)manager;+ (instancetype)managerForDomain:(NSString *)domain;+ (instancetype)managerForAddress:(const void *)address;- (instancetype)initWithReachability:(SCNetworkReachabilityRef)reachability NS_DESIGNATED_INITIALIZER;以上均是初始化方法,我们可以直接用单利模式,比较方便的进行初始化对象,也可以直接用manager,建议还是用单利,因为单利里面也是调用的manager:
+ (instancetype)sharedManager { static AFNetworkReachabilityManager *_sharedManager = nil; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ _sharedManager = [self manager]; }); return _sharedManager;}manager是直接使用的managerForAdress方法:
+ (instancetype)manager{#if (defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && __IPHONE_OS_VERSION_MIN_REQUIRED >= 90000) || (defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 101100) struct sockaddr_in6 address; bzero(&address, sizeof(address)); address.sin6_len = sizeof(address); address.sin6_family = AF_INET6;#else struct sockaddr_in address; bzero(&address, sizeof(address)); address.sin_len = sizeof(address); address.sin_family = AF_INET;#endif return [self managerForAddress:&address];}当然我们也可以使用初始化domain的方法,然后转换成SCNetworkReachabilityRef对象,进行初始化:
+ (instancetype)managerForDomain:(NSString *)domain { SCNetworkReachabilityRef reachability = SCNetworkReachabilityCreateWithName(kCFAllocatorDefault, [domain UTF8String]); AFNetworkReachabilityManager *manager = [[self alloc] initWithReachability:reachability]; CFRelease(reachability); return manager;}
初始化方法里面只是做了一个retain,和初始化网络状态,目测SCNetworkReachabilityRef是不支持自动内存管理的。
- (instancetype)initWithReachability:(SCNetworkReachabilityRef)reachability { self = [super init]; if (!self) { return nil; } _networkReachability = CFRetain(reachability); self.networkReachabilityStatus = AFNetworkReachabilityStatusUnknown; return self;}
2.开始监听网络状态
我们之间调用startMonitoring方法,进行开始网络状态的监控:
- (void)startMonitoring { [self stopMonitoring]; if (!self.networkReachability) { return; } __weak __typeof(self)weakSelf = self; AFNetworkReachabilityStatusBlock callback = ^(AFNetworkReachabilityStatus status) { __strong __typeof(weakSelf)strongSelf = weakSelf; strongSelf.networkReachabilityStatus = status; if (strongSelf.networkReachabilityStatusBlock) { strongSelf.networkReachabilityStatusBlock(status); } }; SCNetworkReachabilityContext context = {0, (__bridge void *)callback, AFNetworkReachabilityRetainCallback, AFNetworkReachabilityReleaseCallback, NULL}; SCNetworkReachabilitySetCallback(self.networkReachability, AFNetworkReachabilityCallback, &context); SCNetworkReachabilityScheduleWithRunLoop(self.networkReachability, CFRunLoopGetMain(), kCFRunLoopCommonModes); dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0),^{ SCNetworkReachabilityFlags flags; if (SCNetworkReachabilityGetFlags(self.networkReachability, &flags)) { AFPostReachabilityStatusChange(flags, callback); } });}使用方法比较简单,此处我们可以看到,做了数据保护工作,如果没有初始化会return,首先先stopMonitoring,这样做可以避免生成多个监听网络的对象,导致收到多个成功的回调。
然后是一个网络状态捕获到的回调。
下面才是使用的SystemConfiguration框架下的SCNetworkReachability的API来做的处理,使用也比较简单,先初始化,然后设置回调block,再对回调的C数据转换成网络状态的枚举类型,最后放到了RunLoop里面,设置到了主RunLoop,并设置model为CommonModes,CommonModes就是普通的和事件处理Mode的集合,不清楚的可以去看RunLoop相关文档。
3.结束监听网络状态
结束也比较简单,当然,我们可以自己调用,也可以不调用。因为在类销毁的时候,dealloc中也调用了这个方法。
- (void)stopMonitoring { if (!self.networkReachability) { return; } SCNetworkReachabilityUnscheduleFromRunLoop(self.networkReachability, CFRunLoopGetMain(), kCFRunLoopCommonModes);}
再看一下网络状态的枚举吧,也就是我们可以捕获到的网络状态有哪些:
typedef NS_ENUM(NSInteger, AFNetworkReachabilityStatus) { AFNetworkReachabilityStatusUnknown = -1, AFNetworkReachabilityStatusNotReachable = 0, AFNetworkReachabilityStatusReachableViaWWAN = 1, AFNetworkReachabilityStatusReachableViaWiFi = 2,};默认是Unknown未知,然后是网络不可达,无线广域网链接,WiFi链接,此处没有区分2G/3G/4G,所以需要使用的小伙伴还得自行处理。
当然AF也为我们提供了获取的属性方法,我们可以直接调用:
@property (readonly, nonatomic, assign, getter = isReachable) BOOL reachable;/** Whether or not the network is currently reachable via WWAN. */@property (readonly, nonatomic, assign, getter = isReachableViaWWAN) BOOL reachableViaWWAN;/** Whether or not the network is currently reachable via WiFi. */@property (readonly, nonatomic, assign, getter = isReachableViaWiFi) BOOL reachableViaWiFi;实现:
- (BOOL)isReachable { return [self isReachableViaWWAN] || [self isReachableViaWiFi];}- (BOOL)isReachableViaWWAN { return self.networkReachabilityStatus == AFNetworkReachabilityStatusReachableViaWWAN;}- (BOOL)isReachableViaWiFi { return self.networkReachabilityStatus == AFNetworkReachabilityStatusReachableViaWiFi;}我们可以看到,我们可以拿到网络是不是可达,当前是不是状态WWAN,WiFi。使用比较方便。
基本就是这些了,如果文中有什么错误,欢迎大家指正。
0 0
- AFNetworking 3.0 源码解析之Reachability
- AFNetworking 3.0 源码解析之Reachability
- AFNetworking 3.0 源码解析之Serialization
- AFNetworking 3.0 源码解析之NSURLSession
- AFNetworking 源码解析之“AFURLSessionManager”
- AFNetworking源码解析<三>
- AFNetworking源码解析<三>
- AFNetworking源码解析<三>
- AFNetworking源码解析<四>
- AFNetworking源码解析<四>
- AFNetworking源码解析https
- AFNetworking源码解析<三>
- AFNetworking-源码解析
- AFNetworking源码解析<三>
- AFNetworking源码解析<四>
- AFNetworking源码解析<三>
- AFNetWorking源码解析
- AFNetworking源码解析<三>
- WTL Hello World
- java运行jar类、scala运行jar类
- PHP关于金额数值的处理,number_format()与round()的使用
- 【51Nod算法马拉松18 A】染色问题
- java基础学习总结--操作符
- AFNetworking 3.0 源码解析之Reachability
- Xcode8上传应用包成功后,iTunes里不显示构建版本
- 移动端WebApp自适应实践
- 电路交换、报文交换和分组交换
- 将binaryproto文件转换为npy文件 代码
- 关于activity的直接传递数据【A向B传递数据】
- 【51Nod算法马拉松18 B】非010串
- 各种图片编码格式详解
- hihocode #1385 : A Simple Job