Quellcode durchsuchen

SessionDelegate now stores Requests internally in preparation for retry logic.

Christian Noon vor 9 Jahren
Ursprung
Commit
8b76a4a09a

+ 17 - 5
Source/Request.swift

@@ -35,7 +35,16 @@ public class Request {
     // MARK: Properties
 
     /// The delegate for the underlying task.
-    public let delegate: TaskDelegate
+    public internal(set) var delegate: TaskDelegate {
+        get {
+            taskDelegateLock.lock() ; defer { taskDelegateLock.unlock() }
+            return taskDelegate
+        }
+        set {
+            taskDelegateLock.lock() ; defer { taskDelegateLock.unlock() }
+            taskDelegate = newValue
+        }
+    }
 
     /// The underlying task.
     public var task: URLSessionTask { return delegate.task }
@@ -66,6 +75,9 @@ public class Request {
     var startTime: CFAbsoluteTime?
     var endTime: CFAbsoluteTime?
 
+    private var taskDelegate: TaskDelegate
+    private var taskDelegateLock = NSLock()
+
     // MARK: Lifecycle
 
     init(session: URLSession, task: URLSessionTask) {
@@ -73,13 +85,13 @@ public class Request {
 
         switch task {
         case is URLSessionUploadTask:
-            delegate = UploadTaskDelegate(task: task)
+            taskDelegate = UploadTaskDelegate(task: task)
         case is URLSessionDataTask:
-            delegate = DataTaskDelegate(task: task)
+            taskDelegate = DataTaskDelegate(task: task)
         case is URLSessionDownloadTask:
-            delegate = DownloadTaskDelegate(task: task)
+            taskDelegate = DownloadTaskDelegate(task: task)
         default:
-            delegate = TaskDelegate(task: task)
+            taskDelegate = TaskDelegate(task: task)
         }
 
         delegate.queue.addOperation { self.endTime = CFAbsoluteTimeGetCurrent() }

+ 17 - 19
Source/SessionDelegate.swift

@@ -123,19 +123,18 @@ public class SessionDelegate: NSObject {
 
     // MARK: Properties
 
-    private var subdelegates: [Int: TaskDelegate] = [:]
-    private let subdelegateQueue = DispatchQueue(label: "Alamofire Sub Delegate Queue", attributes: .concurrent)
+    private var requests: [Int: Request] = [:]
+    private let lock = NSLock()
 
     /// Access the task delegate for the specified task in a thread-safe manner.
-    public subscript(task: URLSessionTask) -> TaskDelegate? {
+    public subscript(task: URLSessionTask) -> Request? {
         get {
-            var subdelegate: TaskDelegate?
-            subdelegateQueue.sync { subdelegate = self.subdelegates[task.taskIdentifier] }
-
-            return subdelegate
+            lock.lock() ; defer { lock.unlock() }
+            return requests[task.taskIdentifier]
         }
         set {
-            subdelegateQueue.async { self.subdelegates[task.taskIdentifier] = newValue }
+            lock.lock() ; defer { lock.unlock() }
+            requests[task.taskIdentifier] = newValue
         }
     }
 
@@ -296,7 +295,7 @@ extension SessionDelegate: URLSessionTaskDelegate {
         if let taskDidReceiveChallenge = taskDidReceiveChallenge {
             let result = taskDidReceiveChallenge(session, task, challenge)
             completionHandler(result.0, result.1)
-        } else if let delegate = self[task] {
+        } else if let delegate = self[task]?.delegate {
             delegate.urlSession(
                 session,
                 task: task,
@@ -325,7 +324,7 @@ extension SessionDelegate: URLSessionTaskDelegate {
 
         if let taskNeedNewBodyStream = taskNeedNewBodyStream {
             completionHandler(taskNeedNewBodyStream(session, task))
-        } else if let delegate = self[task] {
+        } else if let delegate = self[task]?.delegate {
             delegate.urlSession(session, task: task, needNewBodyStream: completionHandler)
         }
     }
@@ -346,7 +345,7 @@ extension SessionDelegate: URLSessionTaskDelegate {
     {
         if let taskDidSendBodyData = taskDidSendBodyData {
             taskDidSendBodyData(session, task, bytesSent, totalBytesSent, totalBytesExpectedToSend)
-        } else if let delegate = self[task] as? UploadTaskDelegate {
+        } else if let delegate = self[task]?.delegate as? UploadTaskDelegate {
             delegate.URLSession(
                 session,
                 task: task,
@@ -365,7 +364,7 @@ extension SessionDelegate: URLSessionTaskDelegate {
     public func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) {
         if let taskDidComplete = taskDidComplete {
             taskDidComplete(session, task, error)
-        } else if let delegate = self[task] {
+        } else if let delegate = self[task]?.delegate {
             delegate.urlSession(session, task: task, didCompleteWithError: error)
         }
 
@@ -423,8 +422,7 @@ extension SessionDelegate: URLSessionDataDelegate {
         if let dataTaskDidBecomeDownloadTask = dataTaskDidBecomeDownloadTask {
             dataTaskDidBecomeDownloadTask(session, dataTask, downloadTask)
         } else {
-            let downloadDelegate = DownloadTaskDelegate(task: downloadTask)
-            self[downloadTask] = downloadDelegate
+            self[downloadTask]?.delegate = DownloadTaskDelegate(task: downloadTask)
         }
     }
 
@@ -436,7 +434,7 @@ extension SessionDelegate: URLSessionDataDelegate {
     public func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive data: Data) {
         if let dataTaskDidReceiveData = dataTaskDidReceiveData {
             dataTaskDidReceiveData(session, dataTask, data)
-        } else if let delegate = self[dataTask] as? DataTaskDelegate {
+        } else if let delegate = self[dataTask]?.delegate as? DataTaskDelegate {
             delegate.urlSession(session, dataTask: dataTask, didReceive: data)
         }
     }
@@ -465,7 +463,7 @@ extension SessionDelegate: URLSessionDataDelegate {
 
         if let dataTaskWillCacheResponse = dataTaskWillCacheResponse {
             completionHandler(dataTaskWillCacheResponse(session, dataTask, proposedResponse))
-        } else if let delegate = self[dataTask] as? DataTaskDelegate {
+        } else if let delegate = self[dataTask]?.delegate as? DataTaskDelegate {
             delegate.urlSession(
                 session,
                 dataTask: dataTask,
@@ -495,7 +493,7 @@ extension SessionDelegate: URLSessionDownloadDelegate {
     {
         if let downloadTaskDidFinishDownloadingToURL = downloadTaskDidFinishDownloadingToURL {
             downloadTaskDidFinishDownloadingToURL(session, downloadTask, location)
-        } else if let delegate = self[downloadTask] as? DownloadTaskDelegate {
+        } else if let delegate = self[downloadTask]?.delegate as? DownloadTaskDelegate {
             delegate.urlSession(session, downloadTask: downloadTask, didFinishDownloadingTo: location)
         }
     }
@@ -519,7 +517,7 @@ extension SessionDelegate: URLSessionDownloadDelegate {
     {
         if let downloadTaskDidWriteData = downloadTaskDidWriteData {
             downloadTaskDidWriteData(session, downloadTask, bytesWritten, totalBytesWritten, totalBytesExpectedToWrite)
-        } else if let delegate = self[downloadTask] as? DownloadTaskDelegate {
+        } else if let delegate = self[downloadTask]?.delegate as? DownloadTaskDelegate {
             delegate.urlSession(
                 session,
                 downloadTask: downloadTask,
@@ -548,7 +546,7 @@ extension SessionDelegate: URLSessionDownloadDelegate {
     {
         if let downloadTaskDidResumeAtOffset = downloadTaskDidResumeAtOffset {
             downloadTaskDidResumeAtOffset(session, downloadTask, fileOffset, expectedTotalBytes)
-        } else if let delegate = self[downloadTask] as? DownloadTaskDelegate {
+        } else if let delegate = self[downloadTask]?.delegate as? DownloadTaskDelegate {
             delegate.urlSession(
                 session,
                 downloadTask: downloadTask,

+ 4 - 4
Source/SessionManager.swift

@@ -247,7 +247,7 @@ public class SessionManager {
         queue.sync { dataTask = self.session.dataTask(with: urlRequest.urlRequest) }
 
         let request = Request(session: session, task: dataTask)
-        delegate[request.delegate.task] = request.delegate
+        delegate[request.delegate.task] = request
 
         if startRequestsImmediately {
             request.resume()
@@ -353,7 +353,7 @@ public class SessionManager {
             }
         }
 
-        delegate[request.delegate.task] = request.delegate
+        delegate[request.delegate.task] = request
 
         if startRequestsImmediately {
             request.resume()
@@ -629,7 +629,7 @@ public class SessionManager {
             }
         }
 
-        delegate[request.delegate.task] = request.delegate
+        delegate[request.delegate.task] = request
 
         if startRequestsImmediately {
             request.resume()
@@ -689,7 +689,7 @@ public class SessionManager {
 
         let request = Request(session: session, task: streamTask)
 
-        delegate[request.delegate.task] = request.delegate
+        delegate[request.delegate.task] = request
 
         if startRequestsImmediately {
             request.resume()

+ 1 - 6
Source/TaskDelegate.swift

@@ -33,7 +33,7 @@ public class TaskDelegate: NSObject {
     /// The serial operation queue used to execute all operations after the task completes.
     public let queue: OperationQueue
 
-    let task: URLSessionTask
+    var task: URLSessionTask
     let progress: Progress
 
     var data: Data? { return nil }
@@ -58,11 +58,6 @@ public class TaskDelegate: NSObject {
         }()
     }
 
-    deinit {
-        queue.cancelAllOperations()
-        queue.isSuspended = false
-    }
-
     // MARK: NSURLSessionTaskDelegate
 
     var taskWillPerformHTTPRedirection: ((URLSession, URLSessionTask, HTTPURLResponse, URLRequest) -> URLRequest?)?

+ 1 - 1
Tests/ValidationTests.swift

@@ -246,7 +246,7 @@ class ContentTypeValidationTestCase: BaseTestCase {
                 }
 
                 let request = MockRequest(session: session, task: dataTask)
-                delegate[request.delegate.task] = request.delegate
+                delegate[request.delegate.task] = request
 
                 if startRequestsImmediately {
                     request.resume()