// // SDLNetworkMonitor.swift // Tun // // Created by 安礼成 on 2024/5/16. // import Foundation import Network import Combine // 监控网络的变化 class SDLNetworkMonitor: @unchecked Sendable { private var monitor: NWPathMonitor private var interfaceType: NWInterface.InterfaceType? private let publisher = PassthroughSubject() private var cancel: AnyCancellable? public let eventStream: AsyncStream private let eventContinuation: AsyncStream.Continuation enum MonitorEvent { case changed case unreachable } init() { self.monitor = NWPathMonitor() (self.eventStream , self.eventContinuation) = AsyncStream.makeStream(of: MonitorEvent.self, bufferingPolicy: .unbounded) } func start() { self.monitor.pathUpdateHandler = {path in if path.status == .satisfied { if path.usesInterfaceType(.wifi) { self.publisher.send(.wifi) } else if path.usesInterfaceType(.cellular) { self.publisher.send(.cellular) } else if path.usesInterfaceType(.wiredEthernet) { self.publisher.send(.wiredEthernet) } } else { self.eventContinuation.yield(.unreachable) self.interfaceType = nil } } self.monitor.start(queue: DispatchQueue.global()) self.cancel = publisher.throttle(for: 5.0, scheduler: DispatchQueue.global(), latest: true) .sink { type in if self.interfaceType != nil && self.interfaceType != type { self.eventContinuation.yield(.changed) } self.interfaceType = type } } deinit { self.monitor.cancel() self.cancel?.cancel() self.eventContinuation.finish() } }