Created
February 21, 2024 07:28
-
-
Save perpeer/f53fefb244597a6d61d243e60f8db3e7 to your computer and use it in GitHub Desktop.
The provided code defines a Ping struct with methods to measure ping time to a given host using both synchronous and asynchronous approaches, leveraging URLSession
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| final class PingVM { | |
| private let session: URLSession | |
| private(set) var pingTime: Int? | |
| init() { | |
| let sessionConfig = URLSessionConfiguration.default | |
| sessionConfig.timeoutIntervalForRequest = 5.0 | |
| sessionConfig.timeoutIntervalForResource = 5.0 | |
| self.session = URLSession(configuration: sessionConfig) | |
| } | |
| func ping() { | |
| Task { | |
| do { | |
| let pingTime = try await Ping.measure( | |
| session: session, | |
| to: "https://www.google.com" | |
| ) | |
| self.pingTime = pingTime | |
| } catch { | |
| self.pingTime = nil | |
| } | |
| } | |
| } | |
| } | |
| enum NetError: Error { | |
| case pingFailure | |
| case cannotCreateURL | |
| } | |
| struct Ping { | |
| static func measure( | |
| session: URLSession, | |
| to host: String, | |
| completion: @escaping (Result<Int, Error>) -> Void | |
| ) { | |
| guard let url = URL(string: host) else { | |
| completion(.failure(NetError.cannotCreateURL)) | |
| return | |
| } | |
| var request = URLRequest(url: url) | |
| request.httpMethod = "HEAD" | |
| let startTime = CFAbsoluteTimeGetCurrent() | |
| session.dataTask(with: request) { _, _, error in | |
| if let error = error { | |
| completion(.failure(error)) | |
| return | |
| } | |
| let endTime = CFAbsoluteTimeGetCurrent() | |
| let elapsedTime = Int((endTime - startTime) * 100) | |
| completion(.success(elapsedTime)) | |
| }.resume() | |
| } | |
| static func measure( | |
| session: URLSession, | |
| to host: String | |
| ) async throws -> Int { | |
| guard let url = URL(string: host) else { | |
| throw NetError.cannotCreateURL | |
| } | |
| var request = URLRequest(url: url) | |
| request.httpMethod = "HEAD" | |
| do { | |
| let startTime = CFAbsoluteTimeGetCurrent() | |
| _ = try await session.data(for: request) | |
| let endTime = CFAbsoluteTimeGetCurrent() | |
| return Int((endTime - startTime) * 100) | |
| } | |
| catch { | |
| throw NetError.pingFailure | |
| } | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment