@@ -18,19 +18,26 @@ internal final class URLSessionSwizzler {
18
18
19
19
/// Swizzles `URLSession.dataTask(with:completionHandler:)` methods (with `URL` and `URLRequest`).
20
20
func swizzle(
21
- interceptCompletionHandler: @escaping ( URLSessionTask , Data ? , Error ? ) -> Void
21
+ interceptCompletionHandler: @escaping ( URLSessionTask , Data ? , Error ? ) -> Void ,
22
+ didReceive: @escaping ( URLSessionTask , Data ) -> Void
22
23
) throws {
23
24
lock. lock ( )
24
25
defer { lock. unlock ( ) }
25
26
dataTaskURLRequestCompletionHandler = try DataTaskURLRequestCompletionHandler . build ( )
26
- dataTaskURLRequestCompletionHandler? . swizzle ( interceptCompletion: interceptCompletionHandler)
27
+ dataTaskURLRequestCompletionHandler? . swizzle (
28
+ interceptCompletion: interceptCompletionHandler,
29
+ didReceive: didReceive
30
+ )
27
31
28
32
if #available( iOS 13 . 0 , * ) {
29
33
// Prior to iOS 13.0 the `URLSession.dataTask(with:url, completionHandler:handler)` makes an internal
30
34
// call to `URLSession.dataTask(with:request, completionHandler:handler)`. To avoid duplicated call
31
35
// to the callback, we don't apply below swizzling prior to iOS 13.
32
36
dataTaskURLCompletionHandler = try DataTaskURLCompletionHandler . build ( )
33
- dataTaskURLCompletionHandler? . swizzle ( interceptCompletion: interceptCompletionHandler)
37
+ dataTaskURLCompletionHandler? . swizzle (
38
+ interceptCompletion: interceptCompletionHandler,
39
+ didReceive: didReceive
40
+ )
34
41
}
35
42
}
36
43
@@ -71,7 +78,8 @@ internal final class URLSessionSwizzler {
71
78
}
72
79
73
80
func swizzle(
74
- interceptCompletion: @escaping ( URLSessionTask , Data ? , Error ? ) -> Void
81
+ interceptCompletion: @escaping ( URLSessionTask , Data ? , Error ? ) -> Void ,
82
+ didReceive: @escaping ( URLSessionTask , Data ) -> Void
75
83
) {
76
84
typealias Signature = @convention ( block) ( URLSession , URLRequest , CompletionHandler ? ) -> URLSessionDataTask
77
85
swizzle ( method) { previousImplementation -> Signature in
@@ -87,13 +95,18 @@ internal final class URLSessionSwizzler {
87
95
88
96
var _task : URLSessionDataTask ?
89
97
let task = previousImplementation ( session, Self . selector, request) { data, response, error in
90
- completionHandler ( data, response, error)
98
+ if let task = _task, let data = data {
99
+ didReceive ( task, data)
100
+ }
91
101
92
102
if let task = _task { // sanity check, should always succeed
93
103
interceptCompletion ( task, data, error)
94
104
}
105
+
106
+ completionHandler ( data, response, error)
95
107
}
96
108
_task = task
109
+ _task? . dd. hasCompletion = true
97
110
return task
98
111
}
99
112
}
@@ -121,7 +134,8 @@ internal final class URLSessionSwizzler {
121
134
}
122
135
123
136
func swizzle(
124
- interceptCompletion: @escaping ( URLSessionTask , Data ? , Error ? ) -> Void
137
+ interceptCompletion: @escaping ( URLSessionTask , Data ? , Error ? ) -> Void ,
138
+ didReceive: @escaping ( URLSessionTask , Data ) -> Void
125
139
) {
126
140
typealias Signature = @convention ( block) ( URLSession , URL , CompletionHandler ? ) -> URLSessionDataTask
127
141
swizzle ( method) { previousImplementation -> Signature in
@@ -137,13 +151,18 @@ internal final class URLSessionSwizzler {
137
151
138
152
var _task : URLSessionDataTask ?
139
153
let task = previousImplementation ( session, Self . selector, url) { data, response, error in
154
+ if let task = _task, let data = data {
155
+ didReceive ( task, data)
156
+ }
157
+
140
158
completionHandler ( data, response, error)
141
159
142
160
if let task = _task { // sanity check, should always succeed
143
161
interceptCompletion ( task, data, error)
144
162
}
145
163
}
146
164
_task = task
165
+ _task? . dd. hasCompletion = true
147
166
return task
148
167
}
149
168
}
0 commit comments