Skip to content

Commit 45d5f48

Browse files
committed
[Netlens] - finish interceptor
1 parent 8c3d004 commit 45d5f48

13 files changed

Lines changed: 147 additions & 135 deletions
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
//
2+
// NetworkCall.swift
3+
// NetLens
4+
//
5+
// Created by NetLens on 09/07/2025.
6+
//
7+
import Foundation
8+
9+
extension NetworkCallDTO {
10+
func toDomain() -> NetworkCall? {
11+
guard let url = URL(string: self.url) else {
12+
return nil
13+
}
14+
15+
let httpMethod = HTTPMethod(rawValue: self.method) ?? .GET
16+
17+
let duration: Duration? = {
18+
guard let timeInterval = self.duration else { return nil }
19+
return Duration.seconds(timeInterval)
20+
}()
21+
22+
let networkError: NetworkError? = {
23+
guard let errorString = self.error else { return nil }
24+
return .networkFailure(errorString)
25+
}()
26+
27+
return NetworkCall(
28+
url: url,
29+
method: httpMethod,
30+
headers: headers,
31+
requestBody: requestBody,
32+
responseBody: responseBody,
33+
statusCode: statusCode,
34+
timeStamp: timeStamp,
35+
duration: duration,
36+
error: networkError
37+
)
38+
}
39+
}
40+

Sources/NetLens/Data/Mappers/NetworkRequestDTO+extension.swift

Lines changed: 0 additions & 20 deletions
This file was deleted.

Sources/NetLens/Data/Mappers/NetworkResponseDTO+extension.swift

Lines changed: 0 additions & 36 deletions
This file was deleted.

Sources/NetLens/Data/Models/NetworkCallDTO.swift

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,22 @@ import Foundation
99

1010
struct NetworkCallDTO: Sendable {
1111

12-
let id: UUID
12+
let timeStamp: Date
1313

14-
let request: NetworkRequestDTO
14+
let url: String
1515

16-
let response: NetworkResponseDTO?
16+
let method: String
1717

18-
let error: String?
18+
let headers: [String: String]
19+
20+
let requestBody: Data?
1921

20-
let timestamp: Date
22+
let responseBody: Data?
2123

22-
let duration: TimeInterval
24+
let statusCode: Int?
2325

26+
let duration: TimeInterval?
27+
28+
let error: String?
2429
}
2530

Sources/NetLens/Data/Models/NetworkRequestDTO.swift

Lines changed: 0 additions & 21 deletions
This file was deleted.

Sources/NetLens/Data/Models/NetworkResponseDTO.swift

Lines changed: 0 additions & 19 deletions
This file was deleted.
Lines changed: 71 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
//
2-
// NetworkCall.swift
2+
// NetLensURLProtocol.swift
33
// NetLens
44
//
55
// Created by NetLens on 08/07/2025.
@@ -8,11 +8,17 @@
88
import Foundation
99

1010
class NetLensURLProtocol: URLProtocol {
11+
1112
@MainActor
1213
static weak var interceptor: URLProtocolNetworkInterceptor?
1314

14-
override class func canInit(with request: URLRequest) -> Bool {
15+
private var networkCallDTO: NetworkCallDTO?
16+
17+
private var dataTask: URLSessionDataTask?
1518

19+
private var startTime: Date?
20+
21+
override class func canInit(with request: URLRequest) -> Bool {
1622
URLProtocol.property(
1723
forKey: "NetLensProcessed",
1824
in: request
@@ -24,18 +30,76 @@ class NetLensURLProtocol: URLProtocol {
2430
}
2531

2632
override func startLoading() {
27-
28-
let mutableRequest = NSMutableURLRequest(url: self.request.url!)
33+
let mutableRequest = (self.request as NSURLRequest).mutableCopy() as! NSMutableURLRequest
2934

3035
URLProtocol.setProperty(
3136
true,
3237
forKey: "NetLensProcessed",
3338
in: mutableRequest
3439
)
3540

36-
}
41+
let startTime = Date()
3742

38-
override func stopLoading() {}
43+
self.networkCallDTO = NetworkCallDTO(
44+
timeStamp: startTime,
45+
url: request.url?.absoluteString ?? "",
46+
method: request.httpMethod ?? "GET",
47+
headers: request.allHTTPHeaderFields ?? [:],
48+
requestBody: request.httpBody,
49+
responseBody: nil,
50+
statusCode: nil,
51+
duration: nil,
52+
error: nil
53+
)
3954

40-
}
55+
let session = URLSession(configuration: .default)
56+
57+
dataTask = session.dataTask(with: mutableRequest as URLRequest) { [weak self] data, response, error in
58+
guard let self else { return }
4159

60+
let endTime = Date()
61+
62+
let duration = self.startTime.map { endTime.timeIntervalSince($0) }
63+
64+
self.networkCallDTO = NetworkCallDTO(
65+
timeStamp: self.networkCallDTO?.timeStamp ?? startTime,
66+
url: self.request.url?.absoluteString ?? "",
67+
method: self.request.httpMethod ?? "GET",
68+
headers: self.request.allHTTPHeaderFields ?? [:],
69+
requestBody: self.request.httpBody,
70+
responseBody: data,
71+
statusCode: (response as? HTTPURLResponse)?.statusCode,
72+
duration: duration,
73+
error: error?.localizedDescription
74+
)
75+
76+
if let networkCallDTO = self.networkCallDTO,
77+
let networkCall = networkCallDTO.toDomain()
78+
{
79+
Task { @MainActor in
80+
await Self.interceptor?.onNetworkCallIntercepted?(networkCall)
81+
}
82+
}
83+
84+
// Gérer la réponse pour le client
85+
if let error = error {
86+
self.client?.urlProtocol(self, didFailWithError: error)
87+
} else {
88+
if let response = response {
89+
self.client?.urlProtocol(self, didReceive: response, cacheStoragePolicy: .notAllowed)
90+
}
91+
if let data = data {
92+
self.client?.urlProtocol(self, didLoad: data)
93+
}
94+
self.client?.urlProtocolDidFinishLoading(self)
95+
}
96+
}
97+
98+
dataTask?.resume()
99+
}
100+
101+
override func stopLoading() {
102+
dataTask?.cancel()
103+
dataTask = nil
104+
}
105+
}

Sources/NetLens/Data/URLProtocolNetworkInterceptor.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ actor URLProtocolNetworkInterceptor: @preconcurrency NetworkInterceptor {
4242
_isEnabled
4343
}
4444

45-
var onNetworkCallIntercepted: ((NetworkCall) async -> Void)?
45+
var onNetworkCallIntercepted: (@Sendable(NetworkCall) async -> Void)?
4646

4747

4848
}

Sources/NetLens/Domain/Entities/NetworkCall.swift

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,3 +99,16 @@ extension NetworkCall {
9999
}
100100
}
101101

102+
struct NetworkRequest: Sendable {
103+
let url: String
104+
let method: String
105+
let headers: [String: String]
106+
let body: Data?
107+
}
108+
109+
struct NetworkResponse: Sendable {
110+
let statusCode: Int
111+
let headers: [String: String]
112+
let body: Data?
113+
}
114+

Sources/NetLens/Domain/Entities/NetworkError.swift

Lines changed: 7 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -8,22 +8,11 @@
88
import Foundation
99

1010
@frozen
11-
public struct NetworkError: Error, Sendable {
12-
public let code: Int
13-
14-
public let message: String
15-
16-
public let underlyingError: String?
17-
18-
public init(
19-
code: Int,
20-
message: String,
21-
underlyingError: Error? = nil
22-
) {
23-
self.code = code
24-
25-
self.message = message
26-
27-
self.underlyingError = underlyingError?.localizedDescription
28-
}
11+
public enum NetworkError: Error, Sendable {
12+
case invalidURL
13+
case noResponse
14+
case networkFailure(String)
15+
case decodingError
16+
case timeout
17+
case unknown
2918
}

0 commit comments

Comments
 (0)