问题描述
我试图使用 Apple 提供的网络框架来实现网络连接,以便我们处理网络问题。
我所做的是: 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,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
}
}
这工作正常,但问题是每当我想在其他视图控制器中使用它时,我都必须复制代码以在 appDidBecomeActive 中再次分配 NetworkMonitor 并制作它appMovedToBackground 中的 nil。
所以请帮助我改进我的方法,以便我只需要在视图控制器中调用 startMonitoring
解决方法
您考虑过 UIApplicationDelegate
方法 applicationWillResignActive(_:)
和 applicationWillEnterForeground(_:)
吗?
另外,让您的 NetworkMonitor
成为单例并在 stopMonitoring()
startMonitoring()
和 UIApplicationDelegate
也是一个好主意