首先,我将从 iOS 的角度来回答这个问题。但是您的 GitHub 演示适用于 macOS。我认为基础是相同的。
我会用面向协议的方法来解决这个问题。
更新:
经过大量搜索,我发现了 Connectivity 包装器的出色实现。如果您想了解更多信息,甚至还有一篇描述性博文Solving the Captive Portal Problem on iOS。 此实现能够处理实际的互联网可用/不可用状态。
注意:不想继续阅读? Here 是我将简要说明的工作版本。导航栏会以 Green 和 Red 颜色反映不同的连接状态。
定义协议:
当连接发生任何变化时,该协议将帮助任何感兴趣的对象得到通知。
protocol ConnectivityNotifiable {
var connectivity: Connectivity { get }
func startNotifyingConnectivityChangeStatus()
func stopNotifyingConnectivityChangeStatus()
func connectivityChanged(toStatus: ConnectivityStatus)
}
// Provide some default implementation through protocol extension
extension ConnectivityNotifiable {
func startNotifyingConnectivityChangeStatus() {
connectivity.isPollingEnabled = true
connectivity.startNotifier()
connectivity.whenConnected = { connectivity in
self.connectivityChanged(toStatus: connectivity.status)
}
connectivity.whenDisconnected = { connectivity in
self.connectivityChanged(toStatus: connectivity.status)
}
}
func stopNotifyingConnectivityChangeStatus() {
connectivity.stopNotifier()
}
}
符合协议:
符合ConnectivityNotifiable 协议将向任何感兴趣的对象添加功能,以便在连接状态更改时得到通知。监控之类的。
class ViewController: UIViewController, ConnectivityNotifiable {
// ConnectivityNotifiable protocol requirement
let connectivity = Connectivity()
override func viewDidLoad() {
super.viewDidLoad()
// Invoke the default implementation of the ConnectivityNotifiable protocol
// requirement to be able to be notified
startNotifyingConnectivityChangeStatus()
// Reminder:
// Don't forget to invoke stopNotifyingConnectivityChangeStatus() when
// you are done or when the lifecycle of your controller ends
}
// ConnectivityNotifiable protocol requirement
func connectivityChanged(toStatus: ConnectivityStatus) {
// Everytime any change happens in the network connectivity
// this method will be invoked with appropriate connection status
switch toStatus {
case .connected,
.connectedViaWiFi,
.connectedViaCellular:
// Connected/Internet available. Update any UI component
case .notConnected,
.connectedViaWiFiWithoutInternet,
.connectedViaCellularWithoutInternet:
// Disconnected/Internet not available. Update any UI component
}
}
}
旧答案
注意:如果您使用的是Reachability 中的最新release,则不需要基于NotificationCenter 的解决方案来获取可达性更改通知。它完全适用于基于闭包的方法。
不想知道如何实现这一目标? Here 是为 iOS 平台制作的工作版本。克隆 repo 并检查自己。导航栏会以 Green、Orange 和 Red 颜色反映不同的连接状态。
定义协议:
当可达性发生任何变化时,该协议将帮助任何感兴趣的对象得到通知。
protocol Reachable {
var reachability: Reachability { get }
func startMonitoringReachabilityChangeStatus()
func reachabilityChanged(to: Reachability.Connection)
}
extension Reachable {
func startMonitoringReachabilityChangeStatus() {
do {
try reachability.startNotifier()
} catch {
print(error.localizedDescription)
}
reachability.whenReachable = { reachability in
self.reachabilityChanged(to: reachability.connection)
}
reachability.whenUnreachable = { reachability in
self.reachabilityChanged(to: reachability.connection)
}
}
}
遵守协议:
符合Reachable 协议将向任何感兴趣的对象添加功能,以便在可达性状态更改时得到通知。监控之类的。
class ViewController: UIViewController, Reachable {
// Reachable protocol requirement
let reachability: Reachability = Reachability()!
override func viewDidLoad() {
super.viewDidLoad()
// initial reachability checkup
reachabilityChanged(to: reachability.connection)
// Invoke the default implementation of the Reachable protocol requirement
// to be able to be notified
startMonitoringReachabilityChangeStatus()
}
// Reachable protocol requirement
func reachabilityChanged(to: Reachability.Connection) {
// Everytime any change happens in the network connectivity
// this method will be invoked with appropriate connection status
switch to {
case .wifi:
DispatchQueue.main.async {
// Update any UI component
}
case .cellular:
DispatchQueue.main.async {
// Update any UI component
}
case .none:
DispatchQueue.main.async {
// Update any UI component
}
}
}
}