AFNetworking 框架小结 五(AFNetworkReachabilityManager)

2024-06-06 13:08

本文主要是介绍AFNetworking 框架小结 五(AFNetworkReachabilityManager),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

AFNetworkReachabilityManager

在 AFNetworking 框架中,提供了一个 AFNetworkReachabilityManager 类用来监控网络状态,其可能的状态如下:

  • AFNetworkReachabilityStatusUnknown 未知状态(-1)
  • AFNetworkReachabilityStatusNotReachable 不可达状态(0)
  • AFNetworkReachabilityStatusReachableViaWWAN 蜂窝网络连通(1)
  • AFNetworkReachabilityStatusReachableViaWiFi 无线网络连通(2)

通过 AFNetworkReachabilityManager 的属性 networkReachabilityStatus 可以获取当前网络的状态,这个属性值是上述状态之一。

还可以通过方法 isReachableisReachableViaWWANisReachableViaWiFi 判断当前网络是否连通或是蜂窝数据连通还是无线网络连通。

AFNetworkReachabilityManager 中提供了多个创建实例的方法,常用的是 sharedManager 方法,这也是 AFURLSessionManager 类中获取网络状态监视器的方法。
该方法获取一个公用的实例对象,其实际上也是调用 manager 方法,创建一个监控默认套接字地址是否可达的监视器。

当然,还可以直接调用 managerForAddress:managerForDomain: 方法来指点要监控的套接字地址或域名地址。

当获取到 AFNetworkReachabilityManager 实例对象后,根据需要可以使用下面的方法设置网络状态发生变化时的回调。

- (void)setReachabilityStatusChangeBlock:(nullable void (^)(AFNetworkReachabilityStatus status))block;

之后,调用实例方法 startMonitoring 便可以开启网络状态监控了,不需要时,可以调用方法 stopMonitoring 关闭监控。

每当网络发生变化时,除了调用设置的回调方法外,还会推送一个 AFNetworkingReachabilityDidChangeNotification 通知,该通知中的 userInfo 信息中的 AFNetworkingReachabilityNotificationStatusItem 包含网络状态信息。

SCNetworkReachabilityRef

网络监控的实现,关键是 SCNetworkReachabilityRef 变量的创建及设置。该变量及其相关的接口可以用来决定当前系统的网络状态,并且可以在网络状态发生变化时,发送通知。

在该接口里也定义了一些常量来标记指定节点域名或地址的网络状态:

  • kSCNetworkReachabilityFlagsTransientConnection 表示指定的节点或地址可以短暂连通,如 PPP
  • kSCNetworkReachabilityFlagsReachable 表示当前网络配置可以连通到指定的节点或地址
  • kSCNetworkReachabilityFlagsConnectionRequired 表示要使用当前网络配置连通到指定地址必需先建立连接,如拨号连接
  • kSCNetworkReachabilityFlagsConnectionOnTraffic 同样需要先建立连接才能传输网络数据,但是每一次传输数据都会初始化连接
  • kSCNetworkReachabilityFlagsConnectionAutomatic 等同于 kSCNetworkReachabilityFlagsConnectionOnTraffic
  • kSCNetworkReachabilityFlagsInterventionRequired 该状态表示除了要先建立连接外,还要提供诸如用户名、密码等信息的网络环境
  • kSCNetworkReachabilityFlagsConnectionOnDemand 该状态表示由 CFSocketStream 接口根据需要建立连接后可以连通到指定地址,其他接口并不会建立连接
  • kSCNetworkReachabilityFlagsIsLocalAddress 表示指定的地址是本地系统的地址
  • kSCNetworkReachabilityFlagsIsDirect 表示连通到指定地址的网络通信不会经过某个网关,而是直接通过本系统的某个接口
  • kSCNetworkReachabilityFlagsIsWWAN 表示指定的网络地址可以通过 EDGE 、GPRS 或其他蜂窝数据连接到达(只用于 iOS 系统)

除了上述的状态概念外,还需要理解一个网络可达性上下文结构,如下:

typedef struct {CFIndex     version;void *      __nullable info;const void  * __nonnull (* __nullable retain)(const void *info);void        (* __nullable release)(const void *info);CFStringRef __nonnull (* __nullable copyDescription)(const void *info);
} SCNetworkReachabilityContext;

在构造使用这个结构体时,version 设置为 0 ,info 是一个指向数据块的 C 指针,retain 是一个含有一个参数和一个返回值的函数,
该回调函数用来对 info 添加引用,与之对应,release 则是用来取消对 info 引用的回调函数,copyDescription 则可以返回对 info 的描述。

该接口里还对回调函数进行了定义:

typedef void (*SCNetworkReachabilityCallBack) (SCNetworkReachabilityRef target,            SCNetworkReachabilityFlags flags,void     *  __nullable  info
);

SCNetworkReachabilityCallBack 指向一个函数,该函数没有返回值,且包含三个参数,受监控的 target ,网络状态变化后的状态 flags ,
以及上下文中的 info 信息,这个信息就是 SCNetworkReachabilityContext 结构体中的 info 成员变量。

理解上面的定义后,现在再来看下面设置回调的函数,则十分简单了。

Boolean SCNetworkReachabilitySetCallback (SCNetworkReachabilityRef target,SCNetworkReachabilityCallBack __nullable callout,SCNetworkReachabilityContext * __nullable context
) __OSX_AVAILABLE_STARTING(__MAC_10_3,__IPHONE_2_0);

三个参数,即为 target 设置回调函数 callout ,同时 callout 关联着 context 上下文,其中可以保存 callout 要用的数据。

在设置回调函数之前,需要使用下面三个函数中的一个创建变量。

//指定一个网络地址
SCNetworkReachabilityRef __nullable SCNetworkReachabilityCreateWithAddress (CFAllocatorRef __nullable allocator,const struct sockaddr *address
) __OSX_AVAILABLE_STARTING(__MAC_10_3,__IPHONE_2_0);//指定网络连接的本地地址和远程地址
SCNetworkReachabilityRef __nullable SCNetworkReachabilityCreateWithAddressPair (CFAllocatorRef __nullable allocator,const struct sockaddr * __nullable localAddress,const struct sockaddr * __nullable remoteAddress
) __OSX_AVAILABLE_STARTING(__MAC_10_3,__IPHONE_2_0);//指定节点域名
SCNetworkReachabilityRef __nullable SCNetworkReachabilityCreateWithName (CFAllocatorRef __nullable allocator,const char *nodename
) __OSX_AVAILABLE_STARTING(__MAC_10_3,__IPHONE_2_0);

前两个方法中都使用下面的结构体保存网络地址:

struct sockaddr {__uint8_t       sa_len;     /* 总长度 */sa_family_t  sa_family; /* 协议簇 */char             sa_data[14];   /* 地址 */
};

上面这个结构体和下面的结构体可以通用

struct sockaddr_in {__uint8_t       sin_len;sa_family_t  sin_family;in_port_t        sin_port;struct  in_addr  sin_addr;char              sin_zero[8]; //为了兼容 sockaddr 结构体而保留的成员变量
};

这两个结构体都占有 16 Bytes 即 sa_lensin_len 的值都是 16 。

创建并设置好 SCNetworkReachabilityRef 变量后,还需要将变量加入到运行循环中,取消监控时,对应的要将该变量移除运行循环。

Boolean SCNetworkReachabilityScheduleWithRunLoop (SCNetworkReachabilityRef target,CFRunLoopRef            runLoop,CFStringRef         runLoopMode
) __OSX_AVAILABLE_STARTING(__MAC_10_3,__IPHONE_2_0);Boolean SCNetworkReachabilityUnscheduleFromRunLoop (SCNetworkReachabilityRef target,CFRunLoopRef            runLoop,CFStringRef         runLoopMode
) __OSX_AVAILABLE_STARTING(__MAC_10_3,__IPHONE_2_0);

另外,还可以使用下面的函数指定回调函数调用的队列:

Boolean SCNetworkReachabilitySetDispatchQueue (SCNetworkReachabilityRef target,dispatch_queue_t __nullable queue
) __OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_4_0);

使用下面的方法获取监控对象的网络状态:

Boolean SCNetworkReachabilityGetFlags (SCNetworkReachabilityRef    target,SCNetworkReachabilityFlags *flags
) __OSX_AVAILABLE_STARTING(__MAC_10_3,__IPHONE_2_0);

startMonitoring

在获取了 AFNetworkReachabilityManager 监视器后,需要调用 startMonitoring 方法来开启监控。

在这个开启方法中,会对创建的 SCNetworkReachabilityRef 变量进行设置,不管这个变量是由域名或地址创建的。

参见下面的源代码:

- (void)startMonitoring {[self stopMonitoring];if (!self.networkReachability) {return;}//这里 callback 与 networkReachabilityStatusBlock 是相同类型的回调代码块//此处进行了包裹,是为了避免 networkReachabilityStatusBlock 为 nil __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};//设置 AFNetworkReachabilityCallback 为回调函数//这个函数中,会对上面的 callback 进行调用,并推送 AFNetworkingReachabilityDidChangeNotification 通知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);}});
}

这篇关于AFNetworking 框架小结 五(AFNetworkReachabilityManager)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1036196

相关文章

cross-plateform 跨平台应用程序-03-如果只选择一个框架,应该选择哪一个?

跨平台系列 cross-plateform 跨平台应用程序-01-概览 cross-plateform 跨平台应用程序-02-有哪些主流技术栈? cross-plateform 跨平台应用程序-03-如果只选择一个框架,应该选择哪一个? cross-plateform 跨平台应用程序-04-React Native 介绍 cross-plateform 跨平台应用程序-05-Flutte

Spring框架5 - 容器的扩展功能 (ApplicationContext)

private static ApplicationContext applicationContext;static {applicationContext = new ClassPathXmlApplicationContext("bean.xml");} BeanFactory的功能扩展类ApplicationContext进行深度的分析。ApplicationConext与 BeanF

数据治理框架-ISO数据治理标准

引言 "数据治理"并不是一个新的概念,国内外有很多组织专注于数据治理理论和实践的研究。目前国际上,主要的数据治理框架有ISO数据治理标准、GDI数据治理框架、DAMA数据治理管理框架等。 ISO数据治理标准 改标准阐述了数据治理的标准、基本原则和数据治理模型,是一套完整的数据治理方法论。 ISO/IEC 38505标准的数据治理方法论的核心内容如下: 数据治理的目标:促进组织高效、合理地

ZooKeeper 中的 Curator 框架解析

Apache ZooKeeper 是一个为分布式应用提供一致性服务的软件。它提供了诸如配置管理、分布式同步、组服务等功能。在使用 ZooKeeper 时,Curator 是一个非常流行的客户端库,它简化了 ZooKeeper 的使用,提供了高级的抽象和丰富的工具。本文将详细介绍 Curator 框架,包括它的设计哲学、核心组件以及如何使用 Curator 来简化 ZooKeeper 的操作。 1

【Kubernetes】K8s 的安全框架和用户认证

K8s 的安全框架和用户认证 1.Kubernetes 的安全框架1.1 认证:Authentication1.2 鉴权:Authorization1.3 准入控制:Admission Control 2.Kubernetes 的用户认证2.1 Kubernetes 的用户认证方式2.2 配置 Kubernetes 集群使用密码认证 Kubernetes 作为一个分布式的虚拟

Spring Framework系统框架

序号表示的是学习顺序 IoC(控制反转)/DI(依赖注入): ioc:思想上是控制反转,spring提供了一个容器,称为IOC容器,用它来充当IOC思想中的外部。 我的理解就是spring把这些对象集中管理,放在容器中,这个容器就叫Ioc这些对象统称为Bean 用对象的时候不用new,直接外部提供(bean) 当外部的对象有关系的时候,IOC给它俩绑好(DI) DI和IO

Sentinel 高可用流量管理框架

Sentinel 是面向分布式服务架构的高可用流量防护组件,主要以流量为切入点,从限流、流量整形、熔断降级、系统负载保护、热点防护等多个维度来帮助开发者保障微服务的稳定性。 Sentinel 具有以下特性: 丰富的应用场景:Sentinel 承接了阿里巴巴近 10 年的双十一大促流量的核心场景,例如秒杀(即突发流量控制在系统容量可以承受的范围)、消息削峰填谷、集群流量控制、实时熔断下游不可用应

分布式系统的个人理解小结

分布式系统:分的微小服务,以小而独立的业务为单位,形成子系统。 然后分布式系统中需要有统一的调用,形成大的聚合服务。 同时,微服务群,需要有交流(通讯,注册中心,同步,异步),有管理(监控,调度)。 对外服务,需要有控制的对外开发,安全网关。

利用Django框架快速构建Web应用:从零到上线

随着互联网的发展,Web应用的需求日益增长,而Django作为一个高级的Python Web框架,以其强大的功能和灵活的架构,成为了众多开发者的选择。本文将指导你如何从零开始使用Django框架构建一个简单的Web应用,并将其部署到线上,让世界看到你的作品。 Django简介 Django是由Adrian Holovaty和Simon Willison于2005年开发的一个开源框架,旨在简

Yii框架relations的使用

通过在 relations() 中声明这些相关对象,我们就可以利用强大的 Relational ActiveRecord (RAR) 功能来访问资讯的相关对象,例如它的作者和评论。不需要自己写复杂的 SQL JOIN 语句。 前提条件 在组织数据库时,需要使用主键与外键约束才能使用ActiveReocrd的关系操作; 场景 申明关系 两张表之间的关系无非三种:一对多;一对一;多对多; 在