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

How to know whether actual internet is available or not in Swift?

我想在我的 WiFi 路由器颜色从 绿色 变为 红色

时收到通知

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

找到

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

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

那么在Swift中有可能知道这个吗?

我检查了代码,你做的方式在互联网连接中断时不会通知你,它只是在运行时检查是否有连接。 为了实现你想要的,我们需要添加 Notifications.

首先声明可达性变量

 private var reachability:Reachability!;

然后在 appdelegate

中的 didFinishLaunchingWithOptions 方法中添加以下代码
 self.reachability = Reachability.init()
         NotificationCenter.default.addObserver(self, selector: #selector(checkForReachability(notification:)), name: .reachabilityChanged, object: reachability)
        do{
            try reachability.startNotifier()
        }catch{
            print("could not start reachability notifier")
        }

我们所做的是初始化可达性变量并创建一个通知观察器,以在通知程序的帮助下检测连接状态何时发生变化。

最后选择器方法是

@objc func checkForReachability(notification:NSNotification)
    {
        let reachability = notification.object as! Reachability
        switch reachability.connection {
        case .wifi:
            print("Reachable via WiFi")
        case .cellular:
            print("Reachable via Cellular")
        case .none:
            print("Network not reachable")
        }
    }

就是这样,从现在开始,当网络连接中断时,我们会收到通知,并且在上面的方法中,您可以更改菜单栏图标的颜色。

首先,我将从iOS的角度来回答这个问题。但是您的 GitHub 演示是针对 macOS 的。我认为基础是一样的。

我将以面向协议的方式解决这个问题。


更新:

经过大量搜索,如果您想了解更多信息,我发现了 Connectivity wrapper. There is even a descriptive blogpost Solving the Captive Portal Problem on iOS 的出色实现。 此实现能够处理实际的互联网可用/不可用状态。

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

定义一个协议:

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

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
        }
    }
}


旧答案

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


不想知道如何实现这一点? Here 是为 iOS 平台制作的工作版本。克隆 repo 并检查你自己。导航栏将以绿色橙色红色颜色反映不同的连接状态。

定义一个协议:

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

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
            }
        }
    }
}