使用 NWPathMonitor 和 BehaviorSubject 来监控网络连接

using NWPathMonitor with BehaviorSubject to monitor network connectivity

我需要一个观察者来让我的应用程序更新设备的连接状态。

NWPathMonitor 似乎是标准方法。所以我是这样的:

class NetworkService {
   let monitor = NWPathMonitor()
   let connected = BehaviorSubject(value: true)
   private init() {
        monitor.pathUpdateHandler = { path in
           let value = path.status == .satisfied
           self.connected.onNext(value)
        }
        let queue = DispatchQueue(label: "NetworkMonitor")
        monitor.start(queue: queue)
   }
}

这是我订阅的地方connected

NetworkService.shared.connected.subscribe(onNext: { connected in
   print("network connected: \(connected)")
}).disposed(by: disposeBag)

应用程序一启动,onNext 就开始疯狂地发射,用 network connected: true 淹没控制台,直到应用程序崩溃。

我尝试添加一个本地缓存变量,这样 onNext 部分只有在值发生变化时才会触发。

if (value != self.previousValue) {
   self.previousValue = value
   self.connected.onNext(value)
}

同样的事情还在发生。所以我猜也许监视器更新太频繁以至于无法分配缓存变量,我尝试添加一个信号量...

self.semaphore.wait()
if (value != self.previousValue) {
    self.previousValue = value
    self.connected.onNext(value)
}
self.semaphore.signal()

还有没有帮助的事件。仍然收到大量打印消息并且应用程序崩溃。

顺便说一句,如果您想知道这就是我在 class:

中声明信号量的方式
let semaphore = DispatchSemaphore( value: 1)

我在 class 中没有看到与您相同的行为,但一个简单的解决方案是使用 .distinctUntilChanged() 这将阻止事件传播,除非它与之前的事件不同.

如果上述不能阻止事件的泛滥,那么问题不在于您提供的代码,而在于您没有告诉我们的其他事情。

另外,我会这样写:

extension NWPathMonitor {
    var rx_path: Observable<NWPath> {
        Observable.create { [self] observer in
            self.pathUpdateHandler = { path in
                observer.onNext(path)
            }
            let queue = DispatchQueue(label: "NetworkMonitor")
            self.start(queue: queue)
            return Disposables.create {
                self.cancel()
            }
        }
    }
}

有了上面的内容,访问起来就很容易了:

let disposable = NWPathMonitor().rx_path
    .map { [=11=].status == .satisfied }
    .debug()
    .subscribe()

订阅将使 NWPathMonitor 对象在订阅期间保持活动状态。对一次性调用 dispose() 将关闭订阅并释放 NWPathMonitor 对象。