iOS AFNetWorking源码详解(四)

[中文教程]
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友 微信微信
查看查看483 回复回复2 收藏收藏 分享淘帖 转播转播 分享分享 微信
查看: 483|回复: 2
收起左侧

[中文教程] iOS AFNetWorking源码详解(四)

[复制链接]
代码买卖 发表于 2016-7-25 02:33:15 | 显示全部楼层 |阅读模式
快来登录
获取优质的苹果资讯内容
收藏热门的iOS等技术干货
拷贝下载Swift Demo源代码
订阅梳理好了的知识点专辑
本帖最后由 代码买卖 于 2016-7-27 22:06 编辑

AFNetworkReachabilityManager是用来监测网络状态的类,可以通过设置状态改变回调来获得当前网络状态

iOS AFNetWorking源码详解

iOS AFNetWorking源码详解(四) - 敏捷大拇指 - iOS AFNetWorking源码详解


网络的状态值有以下四种

[Objective-C] 纯文本查看 复制代码
typedef NS_ENUM(NSInteger, AFNetworkReachabilityStatus) {
    AFNetworkReachabilityStatusUnknown          = -1,// 未知
    AFNetworkReachabilityStatusNotReachable     = 0, // 不可用
    AFNetworkReachabilityStatusReachableViaWWAN = 1, // 无线广域网连接
    AFNetworkReachabilityStatusReachableViaWiFi = 2, // WiFi连接
};


AFNetworkReachabilityManager提供了五种初始化的方法

可以通过单例方法初始化

[Objective-C] 纯文本查看 复制代码
+ (instancetype)sharedManager {
    static AFNetworkReachabilityManager *_sharedManager = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        // 调用+ manager初始化方法
        _sharedManager = [self manager];
    });

    return _sharedManager;
}


单例里面调用了第二种通过默认的socket地址初始化方法,返回一个manager对象,sin_family表示协议族,AF_INET表示TCP/IP协议族的地址

[Objective-C] 纯文本查看 复制代码
+ (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
    // 声明sockaddr_in结构体
    struct sockaddr_in address;
    // address清零
    bzero(&address, sizeof(address));
    // address赋值
    address.sin_len = sizeof(address);
    address.sin_family = AF_INET;
#endif
    // 调用+ [managerForAddress:]方法 
    return [self managerForAddress:&address];
}


在这里又调用了第三种通过传入一个socket地址来初始化

[Objective-C] 纯文本查看 复制代码
+ (instancetype)managerForAddress:(const void *)address {
    // 生成SCNetworkReachabilityRef
    SCNetworkReachabilityRef reachability = SCNetworkReachabilityCreateWithAddress(kCFAllocatorDefault, (const struct sockaddr *)address);
    // 调用- [initWithReachability:]方法
    AFNetworkReachabilityManager *manager = [[self alloc] initWithReachability:reachability];

    CFRelease(reachability);
    
    return manager;
}


里面又调用了第五种初始化方法,因为该方法的后缀里面有NS_DESIGNATED_INITIALIZER,所以最终都会调到它,这里就是做了初始化的工作,将起始的网络状态定为Unknown

[Objective-C] 纯文本查看 复制代码
- (instancetype)initWithReachability:(SCNetworkReachabilityRef)reachability {
    self = [super init];
    if (!self) {
        return nil;
    }

    _networkReachability = CFRetain(reachability);
    self.networkReachabilityStatus = AFNetworkReachabilityStatusUnknown;

    return self;
}


最后剩下一种方法就是可以根据特定的域来初始化

[Objective-C] 纯文本查看 复制代码
+ (instancetype)managerForDomain:(NSString *)domain {
    SCNetworkReachabilityRef reachability = SCNetworkReachabilityCreateWithName(kCFAllocatorDefault, [domain UTF8String]);

    AFNetworkReachabilityManager *manager = [[self alloc] initWithReachability:reachability];
    
    CFRelease(reachability);

    return manager;
}


然后在初始化结束之后,我们需要设置网络状态改变的回调,在开启监听之后,会将网络状态回调给外部

[Objective-C] 纯文本查看 复制代码
- (void)setReachabilityStatusChangeBlock:(void (^)(AFNetworkReachabilityStatus status))block {
    self.networkReachabilityStatusBlock = block;
}


最后就是开启监听

[Objective-C] 纯文本查看 复制代码
- (void)startMonitoring {
    // 停止监听
    [self stopMonitoring];

    if (!self.networkReachability) {
        return;
    }

    // 收到callback调用后,将status通过networkReachabilityStatusBlock回调出去
    __weak __typeof(self)weakSelf = self;
    AFNetworkReachabilityStatusBlock callback = ^(AFNetworkReachabilityStatus status) {
        __strong __typeof(weakSelf)strongSelf = weakSelf;

        strongSelf.networkReachabilityStatus = status;
        if (strongSelf.networkReachabilityStatusBlock) {
            strongSelf.networkReachabilityStatusBlock(status);
        }

    };

          // 声明SCNetworkReachabilityContext结构体
    SCNetworkReachabilityContext context = {0, (__bridge void *)callback, AFNetworkReachabilityRetainCallback, AFNetworkReachabilityReleaseCallback, NULL};
    // 设置回调
          SCNetworkReachabilitySetCallback(self.networkReachability, AFNetworkReachabilityCallback, &context);
    // 加到Main runloop里面对其进行监测
          SCNetworkReachabilityScheduleWithRunLoop(self.networkReachability, CFRunLoopGetMain(), kCFRunLoopCommonModes);
        
          // 获取当前的网络状态,调用callback
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0),^{
        SCNetworkReachabilityFlags flags;
        if (SCNetworkReachabilityGetFlags(self.networkReachability, &flags)) {
            AFPostReachabilityStatusChange(flags, callback);
        }
    });
}


如果没有设置回调的话,也可以通过注册通知的方式,收到网络状态的变化

[Objective-C] 纯文本查看 复制代码
static void AFPostReachabilityStatusChange(SCNetworkReachabilityFlags flags, AFNetworkReachabilityStatusBlock block) {
    // 获取当前的status
          AFNetworkReachabilityStatus status = AFNetworkReachabilityStatusForFlags(flags);
    dispatch_async(dispatch_get_main_queue(), ^{
        // 返回status值
              if (block) {
            block(status);
        }
              // 同时会发送一个通知
        NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
        NSDictionary *userInfo = @{ AFNetworkingReachabilityNotificationStatusItem: @(status) };
        [notificationCenter postNotificationName:AFNetworkingReachabilityDidChangeNotification object:nil userInfo:userInfo];
    });
}


停止监听的话,就是取消在Main Runloop里面的监听

[Objective-C] 纯文本查看 复制代码
- (void)stopMonitoring {
    if (!self.networkReachability) {
        return;
    }

    SCNetworkReachabilityUnscheduleFromRunLoop(self.networkReachability, CFRunLoopGetMain(), kCFRunLoopCommonModes);
}


使用方式例如:

[Objective-C] 纯文本查看 复制代码
AFNetworkReachabilityManager *networkManager = [AFNetworkReachabilityManager sharedManager];
[networkManager startMonitoring];
[networkManager setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) {
    switch (status) {
        case AFNetworkReachabilityStatusNotReachable:
                      // do something
            break;
        case AFNetworkReachabilityStatusReachableViaWWAN:
                      // do something
                      break;
        case AFNetworkReachabilityStatusReachableViaWiFi:
                      // do something
            break;
        default:
            break;
    }
}];





相关内容

iOS AFNetWorking源码详解(一)

iOS AFNetWorking源码详解(二)

iOS AFNetWorking源码详解(三)

iOS AFNetWorking源码详解(四)

iOS AFNetWorking源码详解(五)

iOS AFNetWorking源码详解(六)

AFNetworking 3.0迁移指南 AFNetworking 3.0 Migration Guide




作者:zeeyang

都看到这里了,就把这篇资料推荐给您的好朋友吧,让他们也感受一下。

回帖是一种美德,也是对楼主发帖的尊重和支持。

*声明:敏捷大拇指是全球最大的Swift开发者社区、苹果粉丝家园、智能移动门户,所载内容仅限于传递更多最新信息,并不意味赞同其观点或证实其描述;内容仅供参考,并非绝对正确的建议。本站不对上述信息的真实性、合法性、完整性做出保证;转载请注明来源并加上本站链接,敏捷大拇指将保留所有法律权益。如有疑问或建议,邮件至marketing@swifthumb.com

*联系:微信公众平台:“swifthumb” / 腾讯微博:@swifthumb / 新浪微博:@swifthumb / 官方QQ一群:343549891(满) / 官方QQ二群:245285613 ,需要报上用户名才会被同意进群,请先注册敏捷大拇指

嗯,不错!期待更多好内容,支持一把:
支持敏捷大拇指,用支付宝支付10.24元 支持敏捷大拇指,用微信支付10.24元

本帖被以下淘专辑推荐:

手表哥 发表于 2016-7-29 23:45:09 | 显示全部楼层
多谢了,学习到啦!
1起来 发表于 2016-8-2 12:52:35 | 显示全部楼层
赞!!!
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

做任务,领红包。
我要发帖

分享扩散

都看到这里了,就把这资料推荐给您的好朋友吧,让他们也感受一下。
您的每一位朋友访问此永久链接后,您都将获得相应的金钱积分奖励

相关标签

热门推荐

合作伙伴

Swift小苹果

  • 北京治世天下科技有限公司
  • ©2014-2016 敏捷大拇指
  • 京ICP备14029482号
  • Powered by Discuz! X3.1 Licensed
  • swifthumb Wechat Code
  •   
快速回复 返回顶部 返回列表