Swift 中如何知道实际的互联网是否可用?

dea*_*904 1 notifications reachability ios swift

我希望在我的 WiFi 路由器颜色从绿色变为红色时收到通知

我正在制作一个应用程序,它可以通过 Swift 的菜单栏告诉您是否在线或离线,该应用程序是开源的,可以在https://github.com/deadcoder0904/net-alert找到

我想知道当 Swift 中 WiFi 颜色发生变化时是否可以收到通知。

我无法不断地 ping 我的服务器来知道颜色发生了变化,因为这会浪费互联网资源。

那么在 Swift 中是否可以知道这一点呢?

nay*_*yem 8

首先我从iOS的角度来回答这个问题。但你的 GitHub 演示适用于 macOS。我认为基本原理是相同的。

我将用面向协议的方法来解决这个问题。


更新:

经过大量搜索后,我发现了Connectivity包装器的出色实现。如果您想了解更多信息,甚至还有一篇描述性博文“解决 iOS 上的强制门户问题” 。此实现能够处理实际的互联网可用/不可用状态。

注意:不想继续阅读?是我将简要说明的工作版本。对于不同的连接状态,导航栏将反映为绿色红色

定义一个协议:

当连接发生任何变化时,该协议将帮助任何感兴趣的对象得到通知。

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()
    }
}
Run Code Online (Sandbox Code Playgroud)

符合协议:

符合该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
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

旧答案

注意:如果您使用的是最新版本Reachability,则不需要NotificationCenter基于解决方案来获取可达性更改通知。它与基于闭包的方法完全兼容。


不想知道如何实现这一目标?是为 iOS 平台制作的工作版本。克隆存储库并自行检查。对于不同的连接状态,导航栏将呈现绿色橙色红色

定义一个协议:

当可达性发生任何变化时,该协议将帮助任何感兴趣的对象得到通知。

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)
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

符合协议:

符合该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
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)