Swift监听网络状态
原文:Native Network Monitoring In Swift
此api支持 iOS12+
我们将介绍使用Swift 5在iOS上监控网络连接状态的原生解决方案,以及如何使用Network Link Conditioner。
你将会发现要监听设备网络连接状态,大部分都是依赖第三方框架,如Reachability、Alamofire的NetworkReachabilityManager
,或建议您创建一个定期尝试提出HTTP请求的实用程序,以确定网络连接状态。
相反,我将提供另一种方法,利用iOS 12中引入的不太为人所知的原生框架。
对于这个实现,我们只需要苹果的Network
框架——它就驱动URLSession
的同一框架。虽然当您需要直接访问自定义应用程序协议的TLS、TCP和UDP等协议时,您通常会使用此框架,但我们在这里不会做任何事情。
实现初始化
让我们从创建NetworkMonitor
类开始:
import Networkfinal class NetworkMonitor {static let shared = NetworkMonitor()private let monitor: NWPathMonitorprivate init() {monitor = NWPathMonitor()}
}
NWPathMonitor
是一个观察者,我们可以用它来监控和响应网络变化。
接下来,我们需要创建一些属性来存储网络连接的当前状态:
final class NetworkMonitor {static let shared = NetworkMonitor()private let monitor: NWPathMonitorprivate(set) var isConnected = false/// Checks if the path uses an NWInterface that is considered to/// be expensive////// Cellular interfaces are considered expensive. WiFi hotspots/// from an iOS device are considered expensive. Other/// interfaces may appear as expensive in the future.private(set) var isExpensive = false/// Interface types represent the underlying media for /// a network link////// This can either be `other`, `wifi`, `cellular`, /// `wiredEthernet`, or `loopback`private(set) var currentConnectionType: NWInterface.InterfaceType?private init() {monitor = NWPathMonitor()}
}
我们只需要这些属性是只读的,所以我们在这里选择了
private(set)
)。
我们显然不希望这个长期运行的任务发生在我们应用程序的主线程上,所以让我们创建一个新的DispatchQueue
来管理这项工作:
private let queue = DispatchQueue(label: "NetworkConnectivityMonitor")
Network
框架定义了一个名为NWInterface.InterfaceType
的enum
,该枚举指定了我们的设备可以支持的所有不同媒体类型(WiFi、蜂窝网络、有线以太网等)。
由于此enum
在ObjC中声明,我们无法像在Swift中声明enums
那样访问allCases
属性。因此,我添加了CaseIterable
协议的一致性,并在这里实现了allCases
。由于这个额外的步骤,我们的其余实现将更加简单和可读。
extension NWInterface.InterfaceType: CaseIterable {public static var allCases: [NWInterface.InterfaceType] = [.other,.wifi,.cellular,.loopback,.wiredEthernet]
}
我们实施的最后一步是创建负责启动和停止监控过程的功能:
func startMonitoring() {monitor.pathUpdateHandler = { [weak self] path inself?.isConnected = path.status != .unsatisfiedself?.isExpensive = path.isExpensive// Identifies the current connection type from the// list of potential network link typesself?.currentConnectionType = NWInterface.InterfaceType.allCases.filter { path.usesInterfaceType($0) }.first}monitor.start(queue: queue)
}func stopMonitoring() {monitor.cancel()
}
网络监视动作
只需调用NetworkMonitor.shared.startMonitoring()
,即可从代码中的任何地方开始监控,尽管在大多数情况下,您都希望在AppDelegate
中启动此过程。然后,我们可以使用NetworkMonitor.shared.isConnected
实时检查我们的网络连接状态。
以下是我们迄今为止的执行情况:
import Networkextension NWInterface.InterfaceType: CaseIterable {public static var allCases: [NWInterface.InterfaceType] = [.other,.wifi,.cellular,.loopback,.wiredEthernet]
}final class NetworkMonitor {static let shared = NetworkMonitor()private let queue = DispatchQueue(label: "NetworkConnectivityMonitor")private let monitor: NWPathMonitorprivate(set) var isConnected = falseprivate(set) var isExpensive = falseprivate(set) var currentConnectionType: NWInterface.InterfaceType?private init() {monitor = NWPathMonitor()}func startMonitoring() {monitor.pathUpdateHandler = { [weak self] path inself?.isConnected = path.status != .unsatisfiedself?.isExpensive = path.isExpensiveself?.currentConnectionType = NWInterface.InterfaceType.allCases.filter { path.usesInterfaceType($0) }.first}monitor.start(queue: queue)}func stopMonitoring() {monitor.cancel()}
}
添加通知支持
当设备的网络连接失败时,iOS应用程序的行为发生了巨大变化——一些屏幕可能会显示设备失去连接、应用程序的缓存行为发生变化或某些用户流完全消失的通知。
为了支持此类行为,我们需要扩展我们的实施范围,以便在连接状态发生变化时发送全应用程序范围的通知。
import Foundation
import Networkextension Notification.Name {static let connectivityStatus = Notification.Name(rawValue: "connectivityStatusChanged")
}extension NWInterface.InterfaceType: CaseIterable {public static var allCases: [NWInterface.InterfaceType] = [.other,.wifi,.cellular,.loopback,.wiredEthernet]
}final class NetworkMonitor {static let shared = NetworkMonitor()private let queue = DispatchQueue(label: "NetworkConnectivityMonitor")private let monitor: NWPathMonitorprivate(set) var isConnected = falseprivate(set) var isExpensive = falseprivate(set) var currentConnectionType: NWInterface.InterfaceType?private init() {monitor = NWPathMonitor()}func startMonitoring() {monitor.pathUpdateHandler = { [weak self] path inself?.isConnected = path.status != .unsatisfiedself?.isExpensive = path.isExpensiveself?.currentConnectionType = NWInterface.InterfaceType.allCases.filter { path.usesInterfaceType($0) }.firstNotificationCenter.default.post(name: .connectivityStatus, object: nil)}monitor.start(queue: queue)}func stopMonitoring() {monitor.cancel()}
}// ViewController.swift
class ViewController: UIViewController {override func viewDidLoad() {super.viewDidLoad()NotificationCenter.default.addObserver(self, selector: #selector(showOfflineDeviceUI(notification:)), name: NSNotification.Name.connectivityStatus, object: nil)}@objc func showOfflineDeviceUI(notification: Notification) {if NetworkMonitor.shared.isConnected {print("Connected")} else {print("Not connected")}}
}
您可以在这里找到这个项目的源代码。
Network Link Conditioner 使用
鉴于我们已经在讨论网络和调试连接问题,现在似乎是提及Network Link Confitioner 工具最好机会。
使用此工具,您可以在计算机上模拟不同的网络条件,从而在iOS模拟器上模拟。使用此工具,我们不仅可以监控完全在线或离线的极端情况,还可以根据各种网络条件测试应用程序的行为。
您可以从 Apple Developer 网站或点按此处下载。
网络链接条件器位于您的“系统偏好设置”中
如果您对有关iOS开发和Swift的更多文章感兴趣,请查看我的YouTube频道或在Twitter上关注我。
Swift监听网络状态相关推荐
- 网络安全netstat监听网络状态。
网络安全netstat监听网络状态. Internet的通用语言是TCP/TP,它是一组协议,它规定在网络的第四层运输层有两种协议TCP.UDP.端口就是这两个协议打开的,端口分为源端口和目的端口,源 ...
- Android实时监听网络状态
Android开发实时监听网络状态变化一般有两种方法: 1. 新建一个基类BasicActivity.class,在基类中注册网络监听广播NetworkChangeReceiver.class,所有页 ...
- 初识广播机制(监听网络状态的改变,监听网络是否可以使用)
Android系统中的广播机制比较灵活,因为Android中的每个应用程序都可以对自己感兴趣的广播进行注册,这样该程序就只会接收到自己所关心的广播内容,这些广播可能是来自于系统的,也可能是来自于其他应 ...
- android 监听网络状态
今天,讲讲怎么监听手机网络状态的改变. 一.加入网络权限 获取网络信息需要在AndroidManifest.xml文件中加入相应的权限. <uses-permission android:nam ...
- Android通过使用系统广播监听网络状态的改变
Android通过使用广播监听网络状态的改变 得先添加权限 //查看网络状态<uses-permission android:name="android.permission.ACCE ...
- IOS-网络(监听网络状态)
1 // 2 // BWNetWorkTool.h 3 // IOS_0131_检测网络状态 4 // 5 // Created by ma c on 16/1/31. 6 // Copyright ...
- Android开发动态的监听网络状态的变化
主要思路:使用Android中的四大组件之:BrocastReceiver监听网络状态的变化.接收到网络状态改变的广播之后判断当前的网络是否可用. 创建广播接收器MyNetworkReceiver p ...
- 1.1.14 Electron 监听网络状态
可以用window.addEventListener来进行时间监听网络状态 JavaScript的一种方式进行监听网络状态,监听的事件分别是online和offline. online : 如果链接上 ...
- 使用Service和BroadcastReceiver实时监听网络状态
很多时候我们都需要实时监听网络状态,当网络状态发生变化后通知程序实行不同的策略. 这里,我采用Service+BroadcastReceiver的形式实时监听网络变化. 原理是程序在背后启一个Ser ...
最新文章
- 微信小程序发送模板消息,php发送模板消息
- 12、Kubernetes核心技术Ingress
- PMP-【第3章 项目管理过程】-2021-1-11(61页-87页)
- 常用的图像增强处理办法
- Python推荐算法讲解
- 幂法的c语言程序例子,数值分析之幂法及反幂法C语言程序实例.doc
- 牛客练习赛46T1-华华教奕奕写几何【数学】
- sublime text 2快捷键总结
- 玩转SpringBoot 2.x 解析BeanPostProcessor原理篇
- criteria 排序_产品需求挖掘与排序的2大利器:文本挖掘与KANO模型
- fedora 16 x64 安装gnustep object-c开发环境
- CVPR2018论文阅读-Faster MPN-COV:迭代计算矩阵平方根以快速训练全局协方差池化
- 惠普1020打印机查看已打印页数
- 电容屏物体识别_浅谈多点电容屏物体识别,实物识别技术
- linux 多核 双系统,Linux GRUB实现双系统引导教程
- 富有哲理的10则故事(必读经典)
- 轻松教你苹果airdrop怎么用
- 软件测试好学吗?发展前景如何?
- vue和 element ui下载到本地后引入
- 用 Python 对 Excel 表格内数据进行去重、分类,标记异常及分析
热门文章
- Unbuntu18.04通过apt源方式安装mysql5.7.22
- Oracle 11.2.0.4 x64 RAC扩展存储空间
- 【编码】-小Ho的防护盾-2016.08.14
- 将Button等控件嵌入到repeater中
- mac下的抓包工具Charles
- 一句white-space:nowrap解决IE6,IE7下浮动元素不自动换行
- poj 1474 Video Surveillance - 求多边形有没有核
- 最新、最全面的LAMP+wordpress安装过程!!
- 开始使用linux的core文件
- while 小项目练习