You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Musubi/Packages/MusubiKit/Sources/Remote/Interfaces.swift

55 lines
1.9 KiB

import Foundation
import Network
/// Network interfaces that services can be bound to (e.g. en7 = technical network).
public enum NetworkInterfaces {
public struct Info: Hashable, Sendable, Identifiable {
public var id: String { name }
public let name: String
public let kind: String
}
/// Currently available interfaces (wired, Wi-Fi, other), excluding loopback.
public static func available() async -> [Info] {
await withCheckedContinuation { continuation in
let monitor = NWPathMonitor()
let once = OnceFlag()
monitor.pathUpdateHandler = { path in
guard once.claim() else { return }
monitor.cancel()
continuation.resume(returning: path.availableInterfaces
.filter { $0.type != .loopback }
.map { Info(name: $0.name, kind: describe($0.type)) })
}
monitor.start(queue: .global(qos: .utility))
}
}
static func interface(named name: String) async -> NWInterface? {
await withCheckedContinuation { continuation in
let monitor = NWPathMonitor()
let once = OnceFlag()
monitor.pathUpdateHandler = { path in
guard once.claim() else { return }
monitor.cancel()
continuation.resume(returning: path.availableInterfaces.first { $0.name == name })
}
monitor.start(queue: .global(qos: .utility))
}
}
private static func describe(_ type: NWInterface.InterfaceType) -> String {
switch type {
case .wiredEthernet: "Ethernet"
case .wifi: "WLAN"
default: "Andere"
}
}
}
final class OnceFlag: @unchecked Sendable {
private let lock = NSLock()
private var done = false
func claim() -> Bool { lock.withLock { defer { done = true }; return !done } }
}

Powered by TurnKey Linux.