-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathPlayolaNetworkLoggingSession.swift
More file actions
63 lines (59 loc) · 2.06 KB
/
Copy pathPlayolaNetworkLoggingSession.swift
File metadata and controls
63 lines (59 loc) · 2.06 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
//
// PlayolaNetworkLoggingSession.swift
// PlayolaPlayer
//
// Created by Brian D Keane on 6/4/26.
//
import Foundation
/// A ``URLSessionProtocol`` wrapper that times each call and emits a
/// ``PlayolaNetworkLogEvent`` to ``PlayolaNetworkLogger/handler`` on both
/// success and thrown error.
///
/// It is a transparent pass-through: it returns exactly what the wrapped
/// session returns and rethrows any error unchanged — it never swallows or
/// alters the result. When ``PlayolaNetworkLogger/handler`` is `nil` no event
/// is built and the wrapper adds negligible overhead.
public struct PlayolaNetworkLoggingSession: URLSessionProtocol, Sendable {
private let base: any URLSessionProtocol & Sendable
private let dateProvider: DateProviderProtocol
public init(
wrapping base: any URLSessionProtocol & Sendable,
dateProvider: DateProviderProtocol = DateProvider.shared
) {
self.base = base
self.dateProvider = dateProvider
}
public func data(for request: URLRequest) async throws -> (Data, URLResponse) {
let start = dateProvider.now()
do {
let (data, response) = try await base.data(for: request)
emit(request: request, start: start, data: data, response: response, error: nil)
return (data, response)
} catch {
emit(request: request, start: start, data: nil, response: nil, error: error)
throw error
}
}
private func emit(
request: URLRequest,
start: Date,
data: Data?,
response: URLResponse?,
error: Error?
) {
guard let handler = PlayolaNetworkLogger.handler else { return }
let durationMS = Int(dateProvider.now().timeIntervalSince(start) * 1000)
let event = PlayolaNetworkLogEvent(
timestamp: start,
method: request.httpMethod ?? "GET",
url: request.url,
requestHeaders: request.allHTTPHeaderFields ?? [:],
requestBody: request.httpBody,
statusCode: (response as? HTTPURLResponse)?.statusCode,
responseBody: data,
durationMS: durationMS,
errorDescription: error?.localizedDescription
)
handler(event)
}
}