Skip to content

Commit 4be475e

Browse files
committed
NetworkPath wip
1 parent ebc926e commit 4be475e

4 files changed

Lines changed: 74 additions & 18 deletions

File tree

Package.resolved

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Package.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ let package = Package(
2121
),
2222
],
2323
dependencies: [
24-
.package(url: "https://github.com/codingiran/NetworkKit.git", .upToNextMajor(from: "0.2.4")),
24+
.package(url: "https://github.com/codingiran/NetworkKit.git", .upToNextMajor(from: "0.2.5")),
2525
],
2626
targets: [
2727
// Targets are the basic building blocks of a package, defining a module or a test suite.

[email protected]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ let package = Package(
2121
),
2222
],
2323
dependencies: [
24-
.package(url: "https://github.com/codingiran/NetworkKit.git", .upToNextMajor(from: "0.2.4")),
24+
.package(url: "https://github.com/codingiran/NetworkKit.git", .upToNextMajor(from: "0.2.5")),
2525
],
2626
targets: [
2727
// Targets are the basic building blocks of a package, defining a module or a test suite.

Sources/NetworkPathMonitor/NetworkPath.swift

Lines changed: 69 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,12 @@
77

88
import Foundation
99
import Network
10-
import NetworkKit
10+
11+
#if compiler(>=6.0)
12+
public import NetworkKit
13+
#else
14+
@_exported import NetworkKit
15+
#endif
1116

1217
public struct NetworkPath: Sendable {
1318
/// A status indicating whether a path can be used by connections.
@@ -53,19 +58,46 @@ public struct NetworkPath: Sendable {
5358
return interface
5459
}
5560
}
61+
}
62+
63+
public extension NetworkPath {
64+
/// Network interfaces used by this path
65+
var usedInterfaces: [NetworkKit.Interface] {
66+
availableInterfaces.filter { usesInterfaceType($0.type) }
67+
}
68+
69+
/// Physical network interfaces used by this path, excluding virtual interfaces
70+
var usedPhysicalInterfaces: [NetworkKit.Interface] {
71+
usedInterfaces.filter {
72+
switch $0.type {
73+
case .wifi, .cellular, .wiredEthernet: return true
74+
default: return false
75+
}
76+
}
77+
}
5678

57-
public func usesInterfaceType(_ type: Interface.InterfaceType) -> Bool {
79+
/// The primary used physical network interface, which is the first in the list of used interfaces
80+
var primaryUsedPhysicalInterface: NetworkKit.Interface? { usedInterfaces.first }
81+
82+
/// Checks if the path uses an NWInterface with the specified type
83+
func usesInterfaceType(_ type: Interface.InterfaceType) -> Bool {
5884
rawNWPath.usesInterfaceType(type.nwInterfaceType)
5985
}
6086
}
6187

6288
public extension NetworkPath {
6389
enum Status: Sendable {
64-
case unsatisfied
90+
/// The path has a usable route upon which to send and receive data
6591
case satisfied
92+
93+
/// The path does not have a usable route. This may be due to a network interface being down, or due to system policy.
94+
case unsatisfied
95+
96+
/// The path does not currently have a usable route, but a connection attempt will trigger network attachment.
6697
case requiresConnection
6798

68-
init(nwStatus: NWPath.Status) {
99+
/// Initializes a Status from a NWPath.Status
100+
fileprivate init(nwStatus: NWPath.Status) {
69101
switch nwStatus {
70102
case .satisfied:
71103
self = .satisfied
@@ -80,28 +112,52 @@ public extension NetworkPath {
80112
}
81113

82114
@available(iOS 14.2, macCatalyst 14.2, macOS 11.0, tvOS 14.2, visionOS 1.0, watchOS 7.1, *)
83-
enum UnsatisfiedReason: Sendable {
115+
enum UnsatisfiedReason: Sendable, CustomStringConvertible {
116+
/// No reason is given
117+
case notAvailable
118+
119+
/// The user has disabled cellular
84120
case cellularDenied
121+
122+
/// The user has disabled Wi-Fi
123+
case wifiDenied
124+
125+
/// The user has disabled local network access
85126
case localNetworkDenied
86-
case notAvailable
127+
128+
/// A required VPN is not active
129+
@available(macOS 14.0, iOS 17.0, macCatalyst 17.0, watchOS 10.0, tvOS 17.0, visionOS 1.0, *)
87130
case vpnInactive
88-
case wifiDenied
89131

90-
init(nwUnsatisfiedReason: NWPath.UnsatisfiedReason) {
132+
/// Initializes an UnsatisfiedReason from a NWPath.UnsatisfiedReason
133+
fileprivate init(nwUnsatisfiedReason: NWPath.UnsatisfiedReason) {
91134
switch nwUnsatisfiedReason {
135+
case .notAvailable:
136+
self = .notAvailable
92137
case .cellularDenied:
93138
self = .cellularDenied
139+
case .wifiDenied:
140+
self = .wifiDenied
94141
case .localNetworkDenied:
95142
self = .localNetworkDenied
96-
case .notAvailable:
97-
self = .notAvailable
98143
case .vpnInactive:
99-
self = .vpnInactive
100-
case .wifiDenied:
101-
self = .wifiDenied
144+
if #available(macOS 14.0, iOS 17.0, macCatalyst 17.0, watchOS 10.0, tvOS 17.0, visionOS 1.0, *) {
145+
self = .vpnInactive
146+
}
102147
@unknown default:
103148
fatalError("Unknown NWPath.UnsatisfiedReason value")
104149
}
150+
self = .notAvailable
151+
}
152+
153+
public var description: String {
154+
switch self {
155+
case .cellularDenied: return "Cellular access denied"
156+
case .localNetworkDenied: return "Local network access denied"
157+
case .notAvailable: return "Network not available"
158+
case .vpnInactive: return "VPN is inactive"
159+
case .wifiDenied: return "WiFi access denied"
160+
}
105161
}
106162
}
107163
}

0 commit comments

Comments
 (0)