diff --git a/AmplifyPlugins/Core/AWSPluginsCore/WebSocket/AmplifyNetworkMonitor.swift b/AmplifyPlugins/Core/AWSPluginsCore/WebSocket/AmplifyNetworkMonitor.swift index 23eb1ec4e2..9a4452ee1d 100644 --- a/AmplifyPlugins/Core/AWSPluginsCore/WebSocket/AmplifyNetworkMonitor.swift +++ b/AmplifyPlugins/Core/AWSPluginsCore/WebSocket/AmplifyNetworkMonitor.swift @@ -5,7 +5,7 @@ // SPDX-License-Identifier: Apache-2.0 // - +import Foundation import Network import Combine @@ -19,6 +19,7 @@ public final class AmplifyNetworkMonitor { } private let monitor: NWPathMonitor + private var pingMonitor: AnyCancellable? private let subject = PassthroughSubject() @@ -38,6 +39,8 @@ public final class AmplifyNetworkMonitor { label: "com.amazonaws.amplify.ios.network.websocket.monitor", qos: .userInitiated )) + + pingMonitor = startPingMonitor() } public func updateState(_ nextState: State) { @@ -46,6 +49,35 @@ public final class AmplifyNetworkMonitor { deinit { subject.send(completion: .finished) + pingMonitor?.cancel() monitor.cancel() } + + private func pingGoogle() -> Future { + Future { promise in + let googleDotCom = URL(string: "https://www.google.com")! + var request = URLRequest(url: googleDotCom) + request.httpMethod = "GET" + request.timeoutInterval = .seconds(3) + print("Pinging google.com") + URLSession(configuration: .default).dataTask(with: request) { _, response, error in + if let error { + promise(.success(State.offline)) + } else if let httpResponse = response as? HTTPURLResponse { + promise(.success(httpResponse.statusCode == 200 ? State.online : State.offline)) + } + }.resume() + } + } + + private func startPingMonitor() -> AnyCancellable { + return Timer.TimerPublisher(interval: .seconds(3), runLoop: .main, mode: .default) + .autoconnect() + .receive(on: DispatchQueue.global(qos: .default)) + .compactMap { [weak self] _ in self?.pingGoogle() } + .flatMap { $0 } + .sink { [weak self] state in + self?.updateState(state) + } + } }