Files
byre/mac/Sources/Byre/NetworkWatch.swift
T

55 lines
1.6 KiB
Swift
Raw Normal View History

import Foundation
import Network
#if os(macOS)
import AppKit
#endif
private let networkChanged = Notification.Name("run.fc.byre.networkChanged")
@MainActor
final class NetworkWatch {
static let shared = NetworkWatch()
private let monitor = NWPathMonitor()
private var seen = false
private init() {
monitor.pathUpdateHandler = { [weak self] path in
let summary = "\(path.status) \(path.availableInterfaces.map(\.name).joined(separator: " "))"
Task { @MainActor in
self?.pathChanged(summary)
}
}
monitor.start(queue: .main)
#if os(macOS)
NSWorkspace.shared.notificationCenter.addObserver(forName: NSWorkspace.didWakeNotification, object: nil, queue: .main) { [weak self] _ in
Task { @MainActor in
log.notice("woke from sleep, reconnecting")
self?.post()
}
}
#endif
}
func observe(_ handler: @escaping @MainActor () -> Void) -> any NSObjectProtocol {
NotificationCenter.default.addObserver(forName: networkChanged, object: self, queue: .main) { _ in
MainActor.assumeIsolated {
handler()
}
}
}
private func pathChanged(_ summary: String) {
guard seen else {
seen = true
return
}
log.notice("network changed (\(summary, privacy: .public)), reconnecting")
post()
}
private func post() {
NotificationCenter.default.post(name: networkChanged, object: self)
}
}