@@ -202,36 +202,64 @@ public class URLSessionInstrumentation {
202
202
}
203
203
}
204
204
205
- private func injectIntoNSURLSessionCreateTaskWithParameterMethods( ) {
206
- let cls = URLSession . self
207
- [
208
- #selector( URLSession . uploadTask ( with: from: ) ) ,
209
- #selector( URLSession . uploadTask ( with: fromFile: ) )
210
- ] . forEach {
211
- let selector = $0
212
- guard let original = class_getInstanceMethod ( cls, selector) else {
213
- print ( " injectInto \( selector. description) failed " )
214
- return
215
- }
216
- var originalIMP : IMP ?
217
-
218
- let block :
219
- @convention ( block) ( URLSession , URLRequest , AnyObject ) -> URLSessionTask = { session, request, argument in
220
- let sessionTaskId = UUID ( ) . uuidString
221
- let castedIMP = unsafeBitCast ( originalIMP,
222
- to: ( @convention( c) ( URLSession, Selector, URLRequest, AnyObject)
223
- - > URLSessionDataTask) . self)
224
- let instrumentedRequest = URLSessionLogger . processAndLogRequest ( request, sessionTaskId: sessionTaskId, instrumentation: self ,
225
- shouldInjectHeaders: true )
226
- let task = castedIMP ( session, selector, instrumentedRequest ?? request, argument)
227
- self . setIdKey ( value: sessionTaskId, for: task)
228
- return task
205
+ private func injectIntoNSURLSessionCreateTaskWithParameterMethods( ) {
206
+ typealias UploadWithDataIMP = @convention ( c) ( URLSession , Selector , URLRequest , Data ? ) -> URLSessionTask
207
+ typealias UploadWithFileIMP = @convention ( c) ( URLSession , Selector , URLRequest , URL ) -> URLSessionTask
208
+
209
+ let cls = URLSession . self
210
+
211
+ // MARK: Swizzle `uploadTask(with:from:)`
212
+ if let method = class_getInstanceMethod ( cls, #selector( URLSession . uploadTask ( with: from: ) ) ) {
213
+ let originalIMP = method_getImplementation ( method)
214
+ let imp = unsafeBitCast ( originalIMP, to: UploadWithDataIMP . self)
215
+
216
+ let block : @convention ( block) ( URLSession , URLRequest , Data ? ) -> URLSessionTask = { [ weak self] session, request, data in
217
+ guard let instrumentation = self else {
218
+ return imp ( session, #selector( URLSession . uploadTask ( with: from: ) ) , request, data)
219
+ }
220
+
221
+ let sessionTaskId = UUID ( ) . uuidString
222
+ let instrumentedRequest = URLSessionLogger . processAndLogRequest (
223
+ request,
224
+ sessionTaskId: sessionTaskId,
225
+ instrumentation: instrumentation,
226
+ shouldInjectHeaders: true
227
+ )
228
+
229
+ let task = imp ( session, #selector( URLSession . uploadTask ( with: from: ) ) , instrumentedRequest ?? request, data)
230
+ instrumentation. setIdKey ( value: sessionTaskId, for: task)
231
+ return task
232
+ }
233
+ let swizzledIMP = imp_implementationWithBlock ( block)
234
+ method_setImplementation ( method, swizzledIMP)
235
+ }
236
+
237
+ // MARK: Swizzle `uploadTask(with:fromFile:)`
238
+ if let method = class_getInstanceMethod ( cls, #selector( URLSession . uploadTask ( with: fromFile: ) ) ) {
239
+ let originalIMP = method_getImplementation ( method)
240
+ let imp = unsafeBitCast ( originalIMP, to: UploadWithFileIMP . self)
241
+
242
+ let block : @convention ( block) ( URLSession , URLRequest , URL ) -> URLSessionTask = { [ weak self] session, request, fileURL in
243
+ guard let instrumentation = self else {
244
+ return imp ( session, #selector( URLSession . uploadTask ( with: fromFile: ) ) , request, fileURL)
245
+ }
246
+
247
+ let sessionTaskId = UUID ( ) . uuidString
248
+ let instrumentedRequest = URLSessionLogger . processAndLogRequest (
249
+ request,
250
+ sessionTaskId: sessionTaskId,
251
+ instrumentation: instrumentation,
252
+ shouldInjectHeaders: true
253
+ )
254
+
255
+ let task = imp ( session, #selector( URLSession . uploadTask ( with: fromFile: ) ) , instrumentedRequest ?? request, fileURL)
256
+ instrumentation. setIdKey ( value: sessionTaskId, for: task)
257
+ return task
258
+ }
259
+ let swizzledIMP = imp_implementationWithBlock ( block)
260
+ method_setImplementation ( method, swizzledIMP)
229
261
}
230
- let swizzledIMP = imp_implementationWithBlock (
231
- unsafeBitCast ( block, to: AnyObject . self) )
232
- originalIMP = method_setImplementation ( original, swizzledIMP)
233
262
}
234
- }
235
263
236
264
private func injectIntoNSURLSessionAsyncDataAndDownloadTaskMethods( ) {
237
265
let cls = URLSession . self
0 commit comments