处理网络连接问题的最佳方法- Swift 5



我试图使用苹果提供的网络框架来实现网络连接,以处理网络问题。

我所做的是:1.每当应用程序进入活动状态-我开始监控网络2.当应用程序进入后台时-我取消了监控以降低电池影响

每当我去后台并再次回到应用程序时,我遇到的问题就不会再次监控,因为我们无法再次分配监控实例。我们需要创建新的监视实例来重新开始监视

我正在尽可能地减少冗余代码

所以要实现所有的边情况

下面是我的方法:-

网络监控文件

import Foundation
import Network
final class NetworkMonitor {
private let monitor: NWPathMonitor =  NWPathMonitor()
public private(set) var isConnected:Bool = false
public private(set) var connectionType:ConnectionType = .unknown
init() {
print("init")
let queue = DispatchQueue.global(qos: .background)
monitor.start(queue: queue)
}
public enum ConnectionType {
case cellular
case wifi
case ethernet
case unknown
}

public func startMonitoring() {
monitor.pathUpdateHandler = { [weak self] path in
self?.isConnected = path.status == .satisfied
self?.getConnectionType(path)
NotificationCenter.default.post(name: NSNotification.Name("connectionType"),
object: nil)
}
}
public func stopMonitoring() {
monitor.cancel()
}
private func getConnectionType(_ path:NWPath) {

if path.usesInterfaceType(.wifi) {
connectionType = .wifi
} else if path.usesInterfaceType(.cellular) {
connectionType = .cellular
} else if path.usesInterfaceType(.wiredEthernet) {
connectionType = .ethernet
} else {
connectionType = .unknown
}

}
}

,这是我要监视的视图:

class ViewController: UIViewController {
private var networkMonitor:NetworkMonitor?
private let notificationCenter = NotificationCenter.default
private let networkConnectivityView = NetworkConnectivityView()

override func viewDidLoad() {
super.viewDidLoad()

view.addSubview(networkConnectivityView)
notificationCenter.addObserver(self,
selector: #selector(listeningNetworkConnection),
name: NSNotification.Name("connectionType"),
object: nil)

notificationCenter.addObserver(self, selector: #selector(appDidBecomeActive), name: UIApplication.didBecomeActiveNotification, object: nil)

notificationCenter.addObserver(self, selector: #selector(appMovedToBackground), name: UIApplication.willResignActiveNotification, object: nil)

}

@objc func appDidBecomeActive() {
networkMonitor = NetworkMonitor()
networkMonitor?.startMonitoring()
}
@objc func appMovedToBackground() {

networkMonitor?.stopMonitoring()
networkMonitor = nil
}
@objc private func listeningNetworkConnection() {
DispatchQueue.main.async { [weak self] in
self?.updateUI()
}
}
private func updateUI() {

guard let networkMonitor = networkMonitor else {
return
}

if networkMonitor.isConnected{
print("connected")
networkConnectivityView.configure(with: "Connected")
} else {
print("Not connected")
networkConnectivityView.configure(with: "Not Connected")
}
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()

networkConnectivityView.frame = CGRect(x: 0,
y: 0,
width: view.frame.size.width,
height: 50)
networkConnectivityView.center = view.center
}
}

这是工作得很好,但问题是,每当我想在其他视图控制器中使用这个,我必须复制的代码再次分配NetworkMonitorappDidBecomeActive和使其为nil在appMovedToBackground

所以请帮助我改进我的方法这样我只需要在视图控制器 中调用startMonitoring

您考虑过UIApplicationDelegate方法applicationWillResignActive(_:)applicationWillEnterForeground(_:)吗?也许这是一个好主意,使您的NetworkMonitor为单例,并在UIApplicationDelegate

的各自方法中调用stopMonitoring()startMonitoring()

最新更新