4
4
5
5
import Foundation
6
6
7
- // One more option is to add a delay on connection to make sure logger
8
- // is connected before the app runs.
9
- final class URLSessionMockManager {
7
+ final class URLSessionMockManager : @unchecked Sendable {
10
8
private var mocks : [ UUID : URLSessionMock ] = [ : ]
11
9
10
+ // Number of handled requests per mock.
11
+ private var numberOfHandledRequests : [ UUID : Int ] = [ : ]
12
+ private var mockedTaskIDs : Set < Int > = [ ]
13
+
14
+ private let lock = NSLock ( )
15
+
12
16
static let shared = URLSessionMockManager ( )
13
17
14
18
func getMock( for request: URLRequest ) -> URLSessionMock ? {
15
- mocks. lazy. map ( \. value) . first {
19
+ lock. lock ( )
20
+ defer { lock. unlock ( ) }
21
+
22
+ return mocks. lazy. map ( \. value) . first {
16
23
$0. isMatch ( request)
17
24
}
18
25
}
19
26
27
+ func shouldMock( _ request: URLRequest ) -> Bool {
28
+ lock. lock ( )
29
+ defer { lock. unlock ( ) }
30
+
31
+ guard let mock = getMock ( for: request) else {
32
+ return false
33
+ }
34
+ defer { numberOfHandledRequests [ mock. mockID, default: 0 ] += 1 }
35
+ let count = numberOfHandledRequests [ mock. mockID, default: 0 ]
36
+ if count < ( mock. skip ?? 0 ) {
37
+ return false // Skip the first N requests
38
+ }
39
+ if let maxCount = mock. count, count - ( mock. skip ?? 0 ) >= maxCount {
40
+ return false // Mock for N number of times
41
+ }
42
+ return RemoteLogger . shared. connectionState == . connected
43
+ }
44
+
20
45
func update( _ mocks: [ URLSessionMock ] ) {
46
+ lock. lock ( )
47
+ defer { lock. unlock ( ) }
48
+
21
49
self . mocks. removeAll ( )
22
50
for mock in mocks {
23
51
self . mocks [ mock. mockID] = mock
@@ -27,9 +55,6 @@ final class URLSessionMockManager {
27
55
28
56
final class URLSessionMockingProtocol : URLProtocol {
29
57
override func startLoading( ) {
30
- lock. lock ( )
31
- defer { lock. unlock ( ) }
32
-
33
58
guard let mock = URLSessionMockManager . shared. getMock ( for: request) else {
34
59
client? . urlProtocol ( self , didFailWithError: URLError ( . unknown) ) // Should never happen
35
60
return
@@ -70,27 +95,8 @@ final class URLSessionMockingProtocol: URLProtocol {
70
95
}
71
96
72
97
override class func canInit( with request: URLRequest ) -> Bool {
73
- lock. lock ( )
74
- defer { lock. unlock ( ) }
75
-
76
- guard let mock = URLSessionMockManager . shared. getMock ( for: request) else {
77
- return false
78
- }
79
- defer { numberOfHandledRequests [ mock. mockID, default: 0 ] += 1 }
80
- let count = numberOfHandledRequests [ mock. mockID, default: 0 ]
81
- if count < ( mock. skip ?? 0 ) {
82
- return false // Skip the first N requests
83
- }
84
- if let maxCount = mock. count, count - ( mock. skip ?? 0 ) >= maxCount {
85
- return false // Mock for N number of times
86
- }
87
- return RemoteLogger . shared. connectionState == . connected
98
+ URLSessionMockManager . shared. shouldMock ( request)
88
99
}
89
100
90
101
static let requestMockedHeaderName = " X-PulseRequestMocked "
91
102
}
92
-
93
- // Number of handled requests per mock.
94
- private var numberOfHandledRequests : [ UUID : Int ] = [ : ]
95
- private var mockedTaskIDs : Set < Int > = [ ]
96
- private let lock = NSLock ( )
0 commit comments