温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

iOS12+中检测网络访问的方法是什么

发布时间:2021-11-05 10:11:54 来源:亿速云 阅读:263 作者:iii 栏目:编程语言

本篇内容主要讲解“iOS12+中检测网络访问的方法是什么”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“iOS12+中检测网络访问的方法是什么”吧!

多年来,Apple 的 Reachability 示例程序一直被用作 App 中检测网络访问的基础代码。搜索 Cocoapods.org 将会看到一个很长的第三方库列表,这些库基本上都是基于 Reachability,并考虑了 ARC 的支持或 Swift 的兼容等问题。在 WWDC 2018 上,Apple 介绍了 iOS 12 中的一个新的框架:Network.framework,该框架包含了一个 NWPathMonitor 类。这个类为我们提供了一种监视网络状态变化的方法,而无需包含第三方库或 Apple 示例代码。

使用

只需简单导入 Network 框架,便可以使用 NWPathMonitor 类,如下创建一个 NWPathMonitor 实例:

let monitor = NWPathMonitor()

如果你只对某个特定网络适配器的状态变更感兴趣,例如 Wi-Fi,则可以使用 init(requiredInterfaceType:) 初始化方法,并提供 NWInterface.InterfaceType 值作为参数,来实例化 NWPathMonitor 对象,以监听指定类型的网络适配器,例如:

let monitor = NWPathMonitor(requiredInterfaceType: .wifi)

您需要确保在某处保留对 NWPathMonitor 对象的引用(例如使用 strong 属性),否则 ARC 可能会释放 NWPathMonitor 对象,从而导致指定的回调无法被调用。

可监控的网络类型包括:

cellularloopbackother (对于虚拟或未确定的网络类型)wifiwiredEthernet

要获取状态更改的通知,需要为 pathUpdateHandler 属性指定一个回调,该回调将在网络接口发生状态更改时调用。例如,你的手机网络从蜂窝网络切换到 Wi-Fi 网络。然后,每当发生状态更改时,将返回一个 NWPath 实例,可以使用该实例以确定后续的操作,如下代码:

monitor.pathUpdateHandler = { path in  if path.status == .satisfied {    print("Connected")  }}

使用无参初始化方法与使用指定网络适配器的初始化方法的不同点是:返回的 NWPathobject 对象的 status 属性是否是 satisfied。例如,你只想监听蜂窝网络,而你的手机连接的是 Wi-Fi 网络,则当 Wi-Fi 网络状态发生变化时,并不会调用回调方法,并且 path 的 status 也会保持 unsatisfied 状态,因为手机没有使用指定的网络连接。所以,如果你只想知道是否有网络连接,无论是 Wi-Fi 还是蜂窝,则最好使用无参数的初始化方法。

一个有趣的问题是,NWPath 在 iOS 12 中是作为 Network 框架的一部分,而实际上在 iOS 9 中就有它的身影,不过是在 NetworkExtension.framework,两者之间有一些细微差别。

可以查询返回的 NWPath 对象,以查看设备的网络适配器的状态信息。另一个更有趣的属性是 isExpensive,它标识网络接口返回的数据收费是否昂贵,如使用蜂窝数据。我们同样可以查询是否支持 DNS、IPv4 或 IPv6。我们可以调用 usesInterfaceType 方法,来查看哪个接口改变了状态并触发回调:

let isCellular: Bool = path.usesInterfaceType(.cellular)

使用 NWPathMonitor 有点类似于使用其他 iOS API,例如 CLLocationManager,我们需要调用 start 方法以便开始接收更新,然后在完成后调用对应的 stop 方法。NWPathMonitor 的 start 方法要求我们为对象提供一个队列来执行其工作:

let queue = DispatchQueue.global(qos: .background)monitor.start(queue: queue)

当我们完成监听状态的变化时,我们只需在调用 cancel() 方法。请注意,目前在 NWPathMonitor 上调用 cancel 后,我们无法再次启动监听,而是需要实例化一个新的 NWPathMonitor 实例。请注意,如果在调用 start() 之前访问 NWPathMonitor 的 currentPath 属性,将返回 nil。实际上,如果你打印返回到更新回调的 path,如下所示:

monitor.pathUpdateHandler = { path in  print(path)}

则会打印以下内容:

Optional(satisfied (Path is satisfied), interface: en0, scoped, ipv4, ipv6, dns)

这表明此处返回的 NWPaths 和 currentPath 属性是可选项,尽管 API 没有明确说明(我们可以推断返回的 NWPath 引用是桥接到 Swift 的 Objective-C 指针)。

Captive Portals

Captive Portal 是在公共 Wi-Fi 热点连接时显示的网页,通常用于在授权访问 Internet(或访问其他网络资源)之前强制登录、注册或支付。在之前的一篇博客中,我谈到了从 App 开发的的角度来看,Reachability 看起来好像没什么问题,但实际上由于有 Captive Portals,它并不能很好完成任务。这可能导致 App 无法正常工作甚至于崩溃 -- 因为 App 可能期望从 RESTful API 中获取一些 JSON 数据,却从 Captive Portals 获取到了一些 HTML。

我之前很好奇 NWPathMonitor 在检测网络连接方面是否比 Reachability 有所改进。NWPath.Status 枚举确实提供了三种情况 -- satisfied、 unsatisfied 和 requiresConnection。不幸的是,Network.framework 的开发者文档并未提供这些枚举值的使用说明,而如果我们查看 NetworkExtension.framework 文档,其中的 NWPathStatus 对象提供了 satisfiable 枚举值,里面有一些相关文档描述:

The path is not currently satisfied, but may become satisfied upon a connection attempt. This can be due to a service, such as a VPN or a cellular data connection not being activated.

requiresConnection 枚举值似乎类似于 NWPathStatus 对象的 satisfiable 值。好消息是 NWPathMonitor 通常只在 captive portal 协商之后通知 path 被设置为 satisfiable 状态,即在弹出 web view 且用户登录后。而在没有弹出 captive portal 的情况下,将向用户显示一个 Action Sheet,提供了 Use Without Internet 和 Use Other Network 选项。如果用户选择了 Use Without Internet,则 NWPathMonitor 返回的 path 的状态是 satisfied,即便实际上并没有连网。

通过使用 Charles 做的一些实验,我发现除非选择 Use Without Internet,否则在初始化 Wi-Fi 网络连接的同时中断连接的情况下,NWPathMonitor 没有报告 NWPath 的 Status 被置为 statisfied。但是,如果网络连接已恢复,但随后被删除,则并不能检测到这种变更,并且 path 的状态未依然是 satisfied。如果用户仅在火车或酒店上支付一小时的互联网访问费用,这种情况是可能发生的。

Connectivity

Connectivity 是一个 MIT 许可的开源框架,其目的是复用 iOS 现有的检测 captive portal 的方法。它允许在 iOS 8+ 上使用 Reachability 准确检测真正的 Internet 连接,这意味着在无法使用 NWPathMonitor 时,我们可以使用这个方法。并且在 iOS 12 上,Connectivity 使用了 NWPathMonitor 来提供更高的准确度。

Connectivity 已经提供了对 NWPathMonitor 的支持,可用于 iOS 12+ 系统。如果 framework 属性设置为 network,则会使用 Network 框架来替代 SystemConfiguration 框架(Reachability),以监听网络适配器的状态变更。

let connectivity = Connectivity()connectivity.framework = .network

在网络适配器中的状态更改后,Connectivity 会执行大量检查以确定 Internet 访问是否可用。另外还有一个轮询选项,可以用来轮询网络是否可用,即使状态并未发生改变。可以通过设置 isPollingEnabled = true 并将 pollingInterval 设置为适当的时间值来实现这一点。

到此,相信大家对“iOS12+中检测网络访问的方法是什么”有了更深的了解,不妨来实际操作一番吧!这里是亿速云网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

ios
AI