使用可达性库到基于Swiftui的应用程序来通知网络丢失

我对使用 cocoapods 的 ios && 非常陌生。

我扫描了 SO 以找到检测网络状态的最简单方法,许多答案将我定向到 AshleyMills 的 Reachability git。

我正在 swiftui 中编写我的 webView 应用程序,当用户的互联网连接丢失时,我想弹出一个警报/通知程序。(所以当我的 webview 尝试加载时,他们不会闲着)

如果应用程序打开时网络更改的侦听器继续在后台运行,那将是最好的。

SO 中的大多数答案似乎都是基于 Swift 的(appdelegate、ViewDidload 等),我不知道如何使用,因为我是从 SwiftUI 开始的

提前致谢。

编辑(尝试 Lukas 提供的解决方法)

我尝试了以下。它编译并运行,但警报不会出现。它也不响应连接变化。

我的 ContentView 中有许多子视图。所以我在应用程序级别调用了 timer && 可达性。

@State var currentDate = Date()
let timer = Timer.publish(every: 1, on: .main, in: .common).autoconnect()
let reachability = try! Reachability()

@State private var showAlert: Bool = false

它似乎不起作用:

WindowGroup {
        ContentView()
           .onAppear() {
               if !isConnected() {
                  self.showAlert = true
                  }
               }
           .onReceive(timer) { _ in
               if !isConnected() {
                  self.showAlert = true
           }else{
                  self.showAlert = false
           }
         }
         .alert(isPresented: $showAlert) {
             Alert(title: Text("Error"), message: Text("Your internet connection is too slow."), dismissButton: .default(Text("ok")))
          }
        }

回答

NWPathMonitor是在 iOS 12 中引入的,作为 Reachability 的替代品。一个简单的实现如下。

我们可以公开从 返回的状态pathUpdateHandler,但是这需要您在任何想要使用该状态的地方导入 Network - 并不理想。最好创建自己的枚举来映射到 提供的每个案例NWPath.Status,您可以在此处查看值。我创建了一个只处理连接或未连接状态的程序。

所以我们创建了一个非常简单的 ObservedObject 来发布我们的状态。请注意,当监视器在自己的队列上运行时,我们可能想要更新视图中的内容,我们需要确保我们在主队列上发布。

import Network
import SwiftUI

// An enum to handle the network status
enum NetworkStatus: String {
    case connected
    case disconnected
}

class Monitor: ObservableObject {
    private let monitor = NWPathMonitor()
    private let queue = DispatchQueue(label: "Monitor")

    @Published var status: NetworkStatus = .connected

    init() {
        monitor.pathUpdateHandler = { [weak self] path in
            guard let self = self else { return }

            // Monitor runs on a background thread so we need to publish 
            // on the main thread
            DispatchQueue.main.async {
                if path.status == .satisfied {
                    print("We're connected!")
                    self.status = .connected

                } else {
                    print("No connection.")
                    self.status = .disconnected
                }
            }
        }
        monitor.start(queue: queue)
    }
}

然后我们可以按照我们喜欢的方式使用我们的 Monitor 类,您可以将它用作 StateObject,就像我在下面所做的那样,或者您可以将它用作 EnvironmentObject。这是你的选择。理想情况下,您的应用程序中应该只有此类的一个实例。

struct ContentView: View {
    @StateObject var monitor = Monitor()
    // @EnvironmentObject var monitor: Monitor
    var body: some View {
        Text(monitor.status.rawValue)
    }
}

在运行 iOS 14.2 的 iPad Pro 上的 Playgrounds 中以及在 iOS 14.3 上使用 iPhone X(真实设备)在 Xcode 12.2 上进行测试。


以上是使用可达性库到基于Swiftui的应用程序来通知网络丢失的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>