Swift 并发支持即将推出。
Connectivity 是 Apple Reachability 的一个包装器,它提供了一个可靠的指标来衡量互联网连接是否可用,而 Reachability 只能指示可能允许连接的接口是否可用。
Connectivity 的目标是解决强制门户问题,即 iOS 设备连接到缺少互联网连接的 WiFi 网络。这种情况很常见,例如,当连接到需要用户注册才能使用的公共 WiFi 网络时就可能发生。Connectivity 可以检测到这种情况,使您能够做出相应的反应。
要了解更多关于如何使用 Connectivity 的信息,请查看主题演讲稿,查看博客文章,或使用下面的目录
Connectivity.Publisher
支持 Combine。有关更多信息,请参阅 CHANGELOG.md。
如果您不需要支持 Objective-C 或 iOS 13 之前的 iOS 版本,那么您可能需要考虑使用 Hyperconnectivity(Connectivity 的一个分支项目),它放弃了对这些的支持,转而支持现代、优雅的语法。有关这两个框架的比较,请参阅此处。
Connectivity 和 Hyperconnectivity 都提供对 Combine 的支持,但是如果您在 Combine 不可用的环境中工作,例如支持 iOS 13 之前的 iOS 版本,那么您可以使用 OpenCombine。
OpenConnectivity 使用 OpenCombine 兼容的发布器扩展了 Connectivity,使您能够在 Combine 本身不可用的环境中利用 Combine 语法。
请确保包含 Apple 的 Reachability 头文件和实现文件(Reachability.h 和 Reachability.m)才能使用。
使用 Apple 的 Reachability 需遵守 Apple 的许可。
CocoaPods 是一个依赖管理工具,它将依赖项集成到您的 Xcode 工作区中。要使用 Ruby gems 安装它,请运行
gem install cocoapods
要使用 Cocoapods 安装 Connectivity,只需将以下行添加到您的 Podfile
pod "Connectivity"
然后运行命令
pod install
有关更多信息,请参阅此处。
Carthage 是一个依赖管理工具,它生成一个二进制文件,用于手动集成到您的项目中。可以通过 Homebrew 使用以下命令安装
brew update
brew install carthage
为了通过 Carthage 将 Connectivity 集成到您的项目中,请将以下行添加到您的项目的 Cartfile 中
github "rwbutler/Connectivity"
从 macOS 终端运行 carthage update --platform iOS
以构建框架,然后将 Connectivity.framework
拖到您的 Xcode 项目中。
有关更多信息,请参阅此处。
Xcode(11 及以上版本)包含对 Swift Package Manager 的支持。为了将 Connectivity 添加到您的 Xcode 项目中,从 File
菜单中选择 Swift Packages
,然后选择 Add Package Dependency
。
对话框将请求包仓库 URL,即
https://github.com/rwbutler/connectivity
验证 URL 后,Xcode 将提示您选择是将特定分支、提交还是版本化版本拉取到您的项目中。
继续下一步,您将被要求选择要集成到目标中的包产品。将有一个名为 Connectivity
的单个包产品,它应该被预先选中。确保从对话框的最右列中选择了您的主应用程序目标,然后单击“完成”以完成集成。
iOS 采用了一种名为无线互联网服务提供商漫游 (WISPr 2.0) 的协议,该协议由 无线宽带联盟 发布。该协议定义了智能客户端到接入网关接口,描述了如何使用 通用访问方法 验证访问公共 IEEE 802.11 (Wi-Fi) 网络的用户,其中强制门户向用户呈现登录页面。
然后,用户必须通过 Web 浏览器注册或提供登录凭据,以便使用 RADIUS 或其他协议提供集中式身份验证、授权和计费 (AAA) 来获得网络访问权限。
为了检测到它已连接到带有强制门户的 Wi-Fi 网络,iOS 联系了 Apple 托管的多个端点 - 例如 https://www.apple.com/library/test/success.html。每个端点都托管一个小的 HTML 页面,形式如下
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
<HTML>
<HEAD>
<TITLE>Success</TITLE>
</HEAD>
<BODY>
Success
</BODY>
</HTML>
如果在下载这个小的 HTML 页面时,iOS 发现它包含如上所示的单词 Success
,那么它就知道互联网连接可用。但是,如果强制门户呈现登录页面,则单词 Success
将不会出现,iOS 将意识到网络连接已被强制门户劫持,并将呈现一个浏览器窗口,允许用户登录或注册。
Apple 托管了许多这样的页面,这样,如果其中一个页面出现故障,可以检查许多后备页面,以确定连接是否存在,或者我们的连接是否被强制门户的存在阻止。不幸的是,iOS 没有向开发人员公开任何框架,允许我们利用操作系统对强制门户的感知。
Connectivity 是一个开源框架,它包装了 Reachability,并努力复制 iOS 检测强制门户的方式。当 Reachability 检测到 Wi-Fi 或蜂窝网络连接时,Connectivity 会联系多个端点,以确定是否存在真正的互联网连接,或者强制门户是否正在拦截连接。这种方法也可以用于确定 iOS 设备是否连接到没有互联网接入的 Wi-Fi 路由器。
Connectivity 提供的接口尽可能接近 Reachability,以便熟悉使用 Reachability 的开发人员。这包括提供方法 startNotifier()
和 stopNotifier()
以开始检查互联网连接的变化。一旦启动通知程序,您可以同步使用 status
属性(类似于 Reachability 的 currentReachabilityStatus
)查询当前连接状态,或者通过在默认 NotificationCenter 中注册为通知 kNetworkConnectivityChangedNotification
的观察者来异步查询(在 Swift 中,可以通过 Notification.Name.ConnectivityDidChange
访问)——类似于 Reachability 的通知 kNetworkReachabilityChangedNotification
。
默认情况下,Connectivity 联系了 iOS 已经使用的多个端点,但建议通过附加到 connectivityURLs
属性来替换(或至少补充)由开发人员托管的端点。可以通过设置 successThreshold
属性进行进一步的自定义,该属性确定联系的端点中必须成功检查的百分比,以便得出连接存在的结论。默认值指定联系的 URL 中 50% 必须导致成功的连接性检查。这是因为默认提供了两个连接性 URL,因此只需要两个连接性检查中的一个成功 - 如果您需要更严格的检查,请考虑增加此阈值。
有关如何使用 Connectivity 的示例,请参阅 Example 目录中的示例应用程序。
要开始使用 Connectivity,只需实例化一个实例并分配一个闭包,以便在 Connectivity 检测到您已连接到互联网、断开连接或两种情况时调用,如下所示
let connectivity: Connectivity = Connectivity()
let connectivityChanged: (Connectivity) -> Void = { [weak self] connectivity in
self?.updateConnectionStatus(connectivity.status)
}
connectivity.whenConnected = connectivityChanged
connectivity.whenDisconnected = connectivityChanged
func updateConnectionStatus(_ status: Connectivity.ConnectivityStatus) {
switch status {
case .connected:
case .connectedViaWiFi:
case .connectedViaWiFiWithoutInternet:
case .connectedViaCellular:
case .connectedViaCellularWithoutInternet:
case .notConnected:
}
}
然后调用以下命令开始监听 Connectivity 的变化
connectivity.startNotifier()
然后记住在完成操作后调用 connectivity.stopNotifier()
。
Connectivity 通过提供 Connectivity.Publisher
提供对 Combine 的支持,这允许客户端订阅并接收互联网连接状态更改的通知。
提供的示例应用程序包括 CombineViewController.swift,说明了如何将 Connectivity 与 Combine 框架一起使用,例如
let publisher = Connectivity.Publisher(
configuration:
.init()
.configureURLSession(.default)
)
注意:使用 ConnectivityPublisher
时,您不需要调用 startNotifier
- 这将在订阅时自动为您完成。
可以通过直接在 Connectivity
对象上设置相关属性来配置框架,例如
let connectivity = Connectivity()
connectivity.pollingInterval = 5
connectivity.expectedResponseString = "Success"
connectivity.validationMode = .containsExpectedResponseString
Connectivity 5.2.0 引入了一个新的流畅接口,用于通过将 ConnectivityConfiguration
对象传递给 Connectivity
初始化器来配置框架。
let connectivity = Connectivity(
configuration: .init()
.configurePolling(interval: 5)
.configureResponseValidation(.containsExpectedResponseString, expected: "Success")
)
有时您只想一次性检查连接状态。为此,实例化一个 Connectivity 对象,然后按如下方式检查 status 属性
let connectivity = Connectivity()
connectivity.checkConnectivity { connectivity in
switch connectivity.status {
case .connected:
break
case .connectedViaWiFi:
break
case .connectedViaWiFiWithoutInternet:
break
case .connectedViaCellular:
break
case .connectedViaCellularWithoutInternet:
break
case .notConnected:
break
}
}
或者,如果您只对某些类型的连接感兴趣,您可以直接检查 Connectivity
对象的以下属性
var isConnectedViaCellular: Bool
var isConnectedViaWiFi: Bool
var isConnectedViaCellularWithoutInternet: Bool
var isConnectedViaWiFiWithoutInternet: Bool
可以在使用 startNotifier()
启动连接性检查之前,通过 Connectivity
对象的 connectivityURLs
属性设置将要联系以检查连接性的 URL。
connectivity.connectivityURLs = [URL(string: "https://www.apple.com/library/test/success.html")!]
从 2.0.0 版本开始,Connectivity 提供了在设备运行 iOS 12 或更高版本时使用新的 Network
框架的选项。要使用此功能,请将 framework
属性设置为 .network
(默认值为 .systemConfiguration
),如下所示
let connectivity = Connectivity()
connectivity.framework = .network
在 iOS 12 以下版本中,Connectivity 将默认使用传统的行为,即使用 Reachability
(SystemConfiguration.framework) 来确定网络接口的可用性。
有关更多信息,请参阅 CHANGELOG.md。
如果您更喜欢使用通知来观察连接性变化,您可以在默认 NotificationCenter 上添加一个观察者
NotificationCenter.default.addObserver(_:selector:name:object:)
监听 Notification.Name.ConnectivityDidChange
,接收到的通知的 object
属性将包含 Connectivity
对象,您可以使用它来查询连接性状态。
在某些情况下,您可能需要持续了解连接性状态的变化,因此可能希望启用轮询。在启用轮询的情况下,Connectivity 不会等待 Reachability 状态的变化,而是每 10 秒轮询一次连接性 URL(此值可以通过设置 pollingInterval
属性的值来配置)。只有在连接性状态发生变化时,才会调用 ConnectivityDidChange
通知以及分配给 whenConnected
和 whenDisconnected
属性的闭包。
要启用轮询
connectivity.isPollingEnabled = true
connectivity.startNotifier()
与往常一样,完成操作后请记住调用 stopNotifier()
。
从 Connectivity 1.1.0 开始,对连接性 URL 使用 HTTPS 是默认设置。如果您的应用程序不使用 App Transport Security,并且您希望同时使用 HTTP URL 和 HTTPS URL,则可以将 isHTTPSOnly
设置为 false
,或者在实例化 Connectivity 对象时将 shouldUseHTTPS
设置为 false
,如下所示*
let connectivity = Connectivity(shouldUseHTTPS: false)
*请注意,如果您尚未在应用程序的 Info.plist 中设置 NSAllowsArbitraryLoads
标志,则不会设置该属性。
要设置被视为成功连接所需的成功连接数,请设置 successThreshold
属性。该值以百分比形式指定,表示成功连接的百分比,即,如果在 connectivityURLs
属性中设置了四个连接性 URL,并且指定了 75% 的阈值,则四个检查中必须有三个成功,我们的应用程序才能被视为已连接
connectivity.successThreshold = Connectivity.Percentage(75.0)
有三种不同的验证模式可用于检查响应内容,分别是
.containsExpectedResponseString
- 检查响应包含由 expectedResponseString
属性定义的预期响应。.equalsExpectedResponseString
- 检查响应等于由 expectedResponseString
属性定义的预期响应。.matchesRegularExpression
- 检查响应是否与由 expectedResponseRegEx
属性定义的正则表达式匹配。.custom
- 允许设置自定义响应验证器。如果指定了此验证模式,则必须提供 ConnectivityResponseValidator
协议的实现作为 Connectivity
对象上 responseValidator
属性的值。提供的验证器包括
ConnectivityResponseStringEqualityValidator
:确定响应字符串是否等于预期字符串。ConnectivityResponseContainsStringValidator
:确定响应字符串是否包含预期字符串。ConnectivityResponseRegExValidator
:确定响应字符串是否与给定的正则表达式匹配。请确保任何使用此框架的实现都在其使用期间保持对 Connectivity
对象的强引用(作为实例变量或其他方式)。如果在回调被调用之前对象被释放,则结果将是不确定的。
在报告错误之前,请确保您已在物理设备上进行了测试,因为在模拟器上,网络适配器状态的变化无法被 iOS 框架正确报告,尤其是在从断开连接 -> 连接状态转换时。此行为在物理设备上可以正常运行。设置 pollWhileOfflineOnly = true
应该可以解决此问题。
Connectivity 在 MIT 许可证下可用。有关更多信息,请参阅 LICENSE 文件。
AnimatedGradientView |
---|
![]() |
Cheats | Connectivity | FeatureFlags | 超连接性 | Skylark | TypographyKit | Updates |
---|---|---|---|---|---|---|
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
cdd
即可快速清除您的 DerivedData 目录。Config Validator | IPA Uploader | Palette |
---|---|---|
![]() |
![]() |
![]() |