60 lines
1.6 KiB
Swift
60 lines
1.6 KiB
Swift
|
|
import Foundation
|
||
|
|
import Network
|
||
|
|
import NetworkExtension
|
||
|
|
import Combine
|
||
|
|
|
||
|
|
@MainActor
|
||
|
|
final class LANMonitor: ObservableObject {
|
||
|
|
static let shared = LANMonitor()
|
||
|
|
|
||
|
|
@Published private(set) var isOnNetwork: Bool = false
|
||
|
|
@Published private(set) var currentSSID: String? = nil
|
||
|
|
|
||
|
|
private let monitor = NWPathMonitor()
|
||
|
|
private let queue = DispatchQueue(label: "com.albert.nasbackup.lan", qos: .utility)
|
||
|
|
|
||
|
|
var onTrustedNetworkJoined: ((String) -> Void)?
|
||
|
|
|
||
|
|
private init() {}
|
||
|
|
|
||
|
|
func start() {
|
||
|
|
monitor.pathUpdateHandler = { [weak self] path in
|
||
|
|
guard let self else { return }
|
||
|
|
Task { @MainActor in
|
||
|
|
let satisfied = path.status == .satisfied
|
||
|
|
self.isOnNetwork = satisfied
|
||
|
|
|
||
|
|
if satisfied {
|
||
|
|
await self.checkSSID()
|
||
|
|
} else {
|
||
|
|
self.currentSSID = nil
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
monitor.start(queue: queue)
|
||
|
|
}
|
||
|
|
|
||
|
|
func stop() {
|
||
|
|
monitor.cancel()
|
||
|
|
}
|
||
|
|
|
||
|
|
private func checkSSID() async {
|
||
|
|
let ssid = await fetchCurrentSSID()
|
||
|
|
self.currentSSID = ssid
|
||
|
|
}
|
||
|
|
|
||
|
|
func fetchCurrentSSID() async -> String? {
|
||
|
|
await withCheckedContinuation { continuation in
|
||
|
|
NEHotspotNetwork.fetchCurrent { network in
|
||
|
|
continuation.resume(returning: network?.ssid)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func checkAndTriggerIfTrusted(trustedSSIDs: [String]) async {
|
||
|
|
let ssid = await fetchCurrentSSID()
|
||
|
|
guard let ssid, trustedSSIDs.contains(ssid) else { return }
|
||
|
|
onTrustedNetworkJoined?(ssid)
|
||
|
|
}
|
||
|
|
}
|