Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 10 additions & 2 deletions Sources/OAuthKit/Network/NetworkMonitor.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,17 @@ import Observation
/// An `Observable` type that publishes network reachability information.
@MainActor
@Observable
public final class NetworkMonitor {
public final class NetworkMonitor: Sendable {

// The shared singleton network monitor.
public static let shared: NetworkMonitor = .init()

@ObservationIgnored
private let pathMonitor = NWPathMonitor()

/// Flag indicating if monitoring is currently active or not.
public private(set) var isMonitoring = false

/// Returns true if the network has an available wifi interface.
public var onWifi = false
/// Returns true if the network has an available cellular interface.
Expand All @@ -29,10 +35,12 @@ public final class NetworkMonitor {
}

/// Initializer.
public init() { }
private init() { }

/// Starts the network monitor (conforms to AsyncSequence).
public func start() async {
guard !isMonitoring else { return }
isMonitoring.toggle()
for await path in pathMonitor {
handle(path: path)
}
Expand Down
2 changes: 1 addition & 1 deletion Sources/OAuthKit/OAuth.swift
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ public final class OAuth: Sendable {
private var tasks = [Task<(), any Error>]()

@ObservationIgnored
private let networkMonitor = NetworkMonitor()
private let networkMonitor: NetworkMonitor = .shared

/// Configuration option determining if tokens should be auto refreshed or not.
@ObservationIgnored
Expand Down
11 changes: 9 additions & 2 deletions Tests/OAuthKitTests/UtilityTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ struct UtilityTests {
@MainActor
@Test("Network Monitor")
func whenNetworkMonitoring() async throws {
let monitor = NetworkMonitor()
let monitor: NetworkMonitor = .shared
#expect(monitor.isOnline == false)
withObservationTracking {
_ = monitor.isOnline
Expand All @@ -162,8 +162,15 @@ struct UtilityTests {
#expect(monitor.isOnline)
}
}
Task {
Task { @MainActor in
await monitor.start()
#expect(monitor.isMonitoring)
}
// The second call to monitor.start() should simply bail as monitoring
// is already happening and not toggle the internal `isMonitoring` flag.
Task { @MainActor in
await monitor.start()
#expect(monitor.isMonitoring)
}
}
}
Expand Down