Kaynağa Gözat

Add `@Sendable` to `AdaptHandler` and `RetryHandler` Closure Parameters (#3906)

### Issue Link :link:
Fixes #3905

### Goals :soccer:
This PR adds `@Sendable` to the closure types used by the interceptors.

This PR also normalizes the order of closure attributes to `@escaping
@Sendable`.

### Testing Details :mag:
No tests updated.
Jon Shier 1 yıl önce
ebeveyn
işleme
6efcb40286

+ 12 - 12
Source/Core/DataRequest.swift

@@ -35,7 +35,7 @@ public class DataRequest: Request, @unchecked Sendable {
         var data: Data?
         var httpResponseHandler: (queue: DispatchQueue,
                                   handler: @Sendable (_ response: HTTPURLResponse,
-                                                      _ completionHandler: @Sendable @escaping (ResponseDisposition) -> Void) -> Void)?
+                                                      _ completionHandler: @escaping @Sendable (ResponseDisposition) -> Void) -> Void)?
     }
 
     private let dataMutableState = Protected(DataMutableState())
@@ -93,7 +93,7 @@ public class DataRequest: Request, @unchecked Sendable {
         updateDownloadProgress()
     }
 
-    func didReceiveResponse(_ response: HTTPURLResponse, completionHandler: @Sendable @escaping (URLSession.ResponseDisposition) -> Void) {
+    func didReceiveResponse(_ response: HTTPURLResponse, completionHandler: @escaping @Sendable (URLSession.ResponseDisposition) -> Void) {
         dataMutableState.read { dataMutableState in
             guard let httpResponseHandler = dataMutableState.httpResponseHandler else {
                 underlyingQueue.async { completionHandler(.allow) }
@@ -176,8 +176,8 @@ public class DataRequest: Request, @unchecked Sendable {
     @discardableResult
     public func onHTTPResponse(
         on queue: DispatchQueue = .main,
-        perform handler: @Sendable @escaping (_ response: HTTPURLResponse,
-                                              _ completionHandler: @Sendable @escaping (ResponseDisposition) -> Void) -> Void
+        perform handler: @escaping @Sendable (_ response: HTTPURLResponse,
+                                              _ completionHandler: @escaping @Sendable (ResponseDisposition) -> Void) -> Void
     ) -> Self {
         dataMutableState.write { mutableState in
             mutableState.httpResponseHandler = (queue, handler)
@@ -196,7 +196,7 @@ public class DataRequest: Request, @unchecked Sendable {
     @preconcurrency
     @discardableResult
     public func onHTTPResponse(on queue: DispatchQueue = .main,
-                               perform handler: @Sendable @escaping (HTTPURLResponse) -> Void) -> Self {
+                               perform handler: @escaping @Sendable (HTTPURLResponse) -> Void) -> Self {
         onHTTPResponse(on: queue) { response, completionHandler in
             handler(response)
             completionHandler(.allow)
@@ -241,7 +241,7 @@ public class DataRequest: Request, @unchecked Sendable {
 
     private func _response<Serializer: DataResponseSerializerProtocol>(queue: DispatchQueue = .main,
                                                                        responseSerializer: Serializer,
-                                                                       completionHandler: @Sendable @escaping (AFDataResponse<Serializer.SerializedObject>) -> Void)
+                                                                       completionHandler: @escaping @Sendable (AFDataResponse<Serializer.SerializedObject>) -> Void)
         -> Self {
         appendResponseSerializer {
             // Start work that should be on the serialization queue.
@@ -320,7 +320,7 @@ public class DataRequest: Request, @unchecked Sendable {
     @discardableResult
     public func response<Serializer: DataResponseSerializerProtocol>(queue: DispatchQueue = .main,
                                                                      responseSerializer: Serializer,
-                                                                     completionHandler: @Sendable @escaping (AFDataResponse<Serializer.SerializedObject>) -> Void)
+                                                                     completionHandler: @escaping @Sendable (AFDataResponse<Serializer.SerializedObject>) -> Void)
         -> Self {
         _response(queue: queue, responseSerializer: responseSerializer, completionHandler: completionHandler)
     }
@@ -337,7 +337,7 @@ public class DataRequest: Request, @unchecked Sendable {
     @discardableResult
     public func response<Serializer: ResponseSerializer>(queue: DispatchQueue = .main,
                                                          responseSerializer: Serializer,
-                                                         completionHandler: @Sendable @escaping (AFDataResponse<Serializer.SerializedObject>) -> Void)
+                                                         completionHandler: @escaping @Sendable (AFDataResponse<Serializer.SerializedObject>) -> Void)
         -> Self {
         _response(queue: queue, responseSerializer: responseSerializer, completionHandler: completionHandler)
     }
@@ -359,7 +359,7 @@ public class DataRequest: Request, @unchecked Sendable {
                              dataPreprocessor: any DataPreprocessor = DataResponseSerializer.defaultDataPreprocessor,
                              emptyResponseCodes: Set<Int> = DataResponseSerializer.defaultEmptyResponseCodes,
                              emptyRequestMethods: Set<HTTPMethod> = DataResponseSerializer.defaultEmptyRequestMethods,
-                             completionHandler: @Sendable @escaping (AFDataResponse<Data>) -> Void) -> Self {
+                             completionHandler: @escaping @Sendable (AFDataResponse<Data>) -> Void) -> Self {
         response(queue: queue,
                  responseSerializer: DataResponseSerializer(dataPreprocessor: dataPreprocessor,
                                                             emptyResponseCodes: emptyResponseCodes,
@@ -387,7 +387,7 @@ public class DataRequest: Request, @unchecked Sendable {
                                encoding: String.Encoding? = nil,
                                emptyResponseCodes: Set<Int> = StringResponseSerializer.defaultEmptyResponseCodes,
                                emptyRequestMethods: Set<HTTPMethod> = StringResponseSerializer.defaultEmptyRequestMethods,
-                               completionHandler: @Sendable @escaping (AFDataResponse<String>) -> Void) -> Self {
+                               completionHandler: @escaping @Sendable (AFDataResponse<String>) -> Void) -> Self {
         response(queue: queue,
                  responseSerializer: StringResponseSerializer(dataPreprocessor: dataPreprocessor,
                                                               encoding: encoding,
@@ -417,7 +417,7 @@ public class DataRequest: Request, @unchecked Sendable {
                              emptyResponseCodes: Set<Int> = JSONResponseSerializer.defaultEmptyResponseCodes,
                              emptyRequestMethods: Set<HTTPMethod> = JSONResponseSerializer.defaultEmptyRequestMethods,
                              options: JSONSerialization.ReadingOptions = .allowFragments,
-                             completionHandler: @Sendable @escaping (AFDataResponse<Any>) -> Void) -> Self {
+                             completionHandler: @escaping @Sendable (AFDataResponse<Any>) -> Void) -> Self {
         response(queue: queue,
                  responseSerializer: JSONResponseSerializer(dataPreprocessor: dataPreprocessor,
                                                             emptyResponseCodes: emptyResponseCodes,
@@ -447,7 +447,7 @@ public class DataRequest: Request, @unchecked Sendable {
                                          decoder: any DataDecoder = JSONDecoder(),
                                          emptyResponseCodes: Set<Int> = DecodableResponseSerializer<Value>.defaultEmptyResponseCodes,
                                          emptyRequestMethods: Set<HTTPMethod> = DecodableResponseSerializer<Value>.defaultEmptyRequestMethods,
-                                         completionHandler: @Sendable @escaping (AFDataResponse<Value>) -> Void) -> Self where Value: Decodable, Value: Sendable {
+                                         completionHandler: @escaping @Sendable (AFDataResponse<Value>) -> Void) -> Self where Value: Decodable, Value: Sendable {
         response(queue: queue,
                  responseSerializer: DecodableResponseSerializer(dataPreprocessor: dataPreprocessor,
                                                                  decoder: decoder,

+ 5 - 5
Source/Core/DataStreamRequest.swift

@@ -99,7 +99,7 @@ public final class DataStreamRequest: Request, @unchecked Sendable {
         /// Handler for any `HTTPURLResponse`s received.
         var httpResponseHandler: (queue: DispatchQueue,
                                   handler: @Sendable (_ response: HTTPURLResponse,
-                                                      _ completionHandler: @Sendable @escaping (ResponseDisposition) -> Void) -> Void)?
+                                                      _ completionHandler: @escaping @Sendable (ResponseDisposition) -> Void) -> Void)?
     }
 
     let streamMutableState = Protected(StreamMutableState())
@@ -168,7 +168,7 @@ public final class DataStreamRequest: Request, @unchecked Sendable {
         }
     }
 
-    func didReceiveResponse(_ response: HTTPURLResponse, completionHandler: @Sendable @escaping (URLSession.ResponseDisposition) -> Void) {
+    func didReceiveResponse(_ response: HTTPURLResponse, completionHandler: @escaping @Sendable (URLSession.ResponseDisposition) -> Void) {
         streamMutableState.read { dataMutableState in
             guard let httpResponseHandler = dataMutableState.httpResponseHandler else {
                 underlyingQueue.async { completionHandler(.allow) }
@@ -258,8 +258,8 @@ public final class DataStreamRequest: Request, @unchecked Sendable {
     @discardableResult
     public func onHTTPResponse(
         on queue: DispatchQueue = .main,
-        perform handler: @Sendable @escaping (_ response: HTTPURLResponse,
-                                              _ completionHandler: @Sendable @escaping (ResponseDisposition) -> Void) -> Void
+        perform handler: @escaping @Sendable (_ response: HTTPURLResponse,
+                                              _ completionHandler: @escaping @Sendable (ResponseDisposition) -> Void) -> Void
     ) -> Self {
         streamMutableState.write { mutableState in
             mutableState.httpResponseHandler = (queue, handler)
@@ -278,7 +278,7 @@ public final class DataStreamRequest: Request, @unchecked Sendable {
     @preconcurrency
     @discardableResult
     public func onHTTPResponse(on queue: DispatchQueue = .main,
-                               perform handler: @Sendable @escaping (HTTPURLResponse) -> Void) -> Self {
+                               perform handler: @escaping @Sendable (HTTPURLResponse) -> Void) -> Self {
         onHTTPResponse(on: queue) { response, completionHandler in
             handler(response)
             completionHandler(.allow)

+ 10 - 10
Source/Core/DownloadRequest.swift

@@ -252,7 +252,7 @@ public final class DownloadRequest: Request, @unchecked Sendable {
     /// - Returns:                     The instance.
     @preconcurrency
     @discardableResult
-    public func cancel(byProducingResumeData completionHandler: @Sendable @escaping (_ data: Data?) -> Void) -> Self {
+    public func cancel(byProducingResumeData completionHandler: @escaping @Sendable (_ data: Data?) -> Void) -> Self {
         cancel(optionallyProducingResumeData: completionHandler)
     }
 
@@ -336,7 +336,7 @@ public final class DownloadRequest: Request, @unchecked Sendable {
     @preconcurrency
     @discardableResult
     public func response(queue: DispatchQueue = .main,
-                         completionHandler: @Sendable @escaping (AFDownloadResponse<URL?>) -> Void)
+                         completionHandler: @escaping @Sendable (AFDownloadResponse<URL?>) -> Void)
         -> Self {
         appendResponseSerializer {
             // Start work that should be on the serialization queue.
@@ -363,7 +363,7 @@ public final class DownloadRequest: Request, @unchecked Sendable {
 
     private func _response<Serializer: DownloadResponseSerializerProtocol>(queue: DispatchQueue = .main,
                                                                            responseSerializer: Serializer,
-                                                                           completionHandler: @Sendable @escaping (AFDownloadResponse<Serializer.SerializedObject>) -> Void)
+                                                                           completionHandler: @escaping @Sendable (AFDownloadResponse<Serializer.SerializedObject>) -> Void)
         -> Self {
         appendResponseSerializer {
             // Start work that should be on the serialization queue.
@@ -445,7 +445,7 @@ public final class DownloadRequest: Request, @unchecked Sendable {
     @discardableResult
     public func response<Serializer: DownloadResponseSerializerProtocol>(queue: DispatchQueue = .main,
                                                                          responseSerializer: Serializer,
-                                                                         completionHandler: @Sendable @escaping (AFDownloadResponse<Serializer.SerializedObject>) -> Void)
+                                                                         completionHandler: @escaping @Sendable (AFDownloadResponse<Serializer.SerializedObject>) -> Void)
         -> Self {
         _response(queue: queue, responseSerializer: responseSerializer, completionHandler: completionHandler)
     }
@@ -464,7 +464,7 @@ public final class DownloadRequest: Request, @unchecked Sendable {
     @discardableResult
     public func response<Serializer: ResponseSerializer>(queue: DispatchQueue = .main,
                                                          responseSerializer: Serializer,
-                                                         completionHandler: @Sendable @escaping (AFDownloadResponse<Serializer.SerializedObject>) -> Void)
+                                                         completionHandler: @escaping @Sendable (AFDownloadResponse<Serializer.SerializedObject>) -> Void)
         -> Self {
         _response(queue: queue, responseSerializer: responseSerializer, completionHandler: completionHandler)
     }
@@ -479,7 +479,7 @@ public final class DownloadRequest: Request, @unchecked Sendable {
     @preconcurrency
     @discardableResult
     public func responseURL(queue: DispatchQueue = .main,
-                            completionHandler: @Sendable @escaping (AFDownloadResponse<URL>) -> Void) -> Self {
+                            completionHandler: @escaping @Sendable (AFDownloadResponse<URL>) -> Void) -> Self {
         response(queue: queue, responseSerializer: URLResponseSerializer(), completionHandler: completionHandler)
     }
 
@@ -502,7 +502,7 @@ public final class DownloadRequest: Request, @unchecked Sendable {
                              dataPreprocessor: any DataPreprocessor = DataResponseSerializer.defaultDataPreprocessor,
                              emptyResponseCodes: Set<Int> = DataResponseSerializer.defaultEmptyResponseCodes,
                              emptyRequestMethods: Set<HTTPMethod> = DataResponseSerializer.defaultEmptyRequestMethods,
-                             completionHandler: @Sendable @escaping (AFDownloadResponse<Data>) -> Void) -> Self {
+                             completionHandler: @escaping @Sendable (AFDownloadResponse<Data>) -> Void) -> Self {
         response(queue: queue,
                  responseSerializer: DataResponseSerializer(dataPreprocessor: dataPreprocessor,
                                                             emptyResponseCodes: emptyResponseCodes,
@@ -532,7 +532,7 @@ public final class DownloadRequest: Request, @unchecked Sendable {
                                encoding: String.Encoding? = nil,
                                emptyResponseCodes: Set<Int> = StringResponseSerializer.defaultEmptyResponseCodes,
                                emptyRequestMethods: Set<HTTPMethod> = StringResponseSerializer.defaultEmptyRequestMethods,
-                               completionHandler: @Sendable @escaping (AFDownloadResponse<String>) -> Void) -> Self {
+                               completionHandler: @escaping @Sendable (AFDownloadResponse<String>) -> Void) -> Self {
         response(queue: queue,
                  responseSerializer: StringResponseSerializer(dataPreprocessor: dataPreprocessor,
                                                               encoding: encoding,
@@ -564,7 +564,7 @@ public final class DownloadRequest: Request, @unchecked Sendable {
                              emptyResponseCodes: Set<Int> = JSONResponseSerializer.defaultEmptyResponseCodes,
                              emptyRequestMethods: Set<HTTPMethod> = JSONResponseSerializer.defaultEmptyRequestMethods,
                              options: JSONSerialization.ReadingOptions = .allowFragments,
-                             completionHandler: @Sendable @escaping (AFDownloadResponse<Any>) -> Void) -> Self {
+                             completionHandler: @escaping @Sendable (AFDownloadResponse<Any>) -> Void) -> Self {
         response(queue: queue,
                  responseSerializer: JSONResponseSerializer(dataPreprocessor: dataPreprocessor,
                                                             emptyResponseCodes: emptyResponseCodes,
@@ -596,7 +596,7 @@ public final class DownloadRequest: Request, @unchecked Sendable {
                                                 decoder: any DataDecoder = JSONDecoder(),
                                                 emptyResponseCodes: Set<Int> = DecodableResponseSerializer<T>.defaultEmptyResponseCodes,
                                                 emptyRequestMethods: Set<HTTPMethod> = DecodableResponseSerializer<T>.defaultEmptyRequestMethods,
-                                                completionHandler: @Sendable @escaping (AFDownloadResponse<T>) -> Void) -> Self where T: Sendable {
+                                                completionHandler: @escaping @Sendable (AFDownloadResponse<T>) -> Void) -> Self where T: Sendable {
         response(queue: queue,
                  responseSerializer: DecodableResponseSerializer(dataPreprocessor: dataPreprocessor,
                                                                  decoder: decoder,

+ 7 - 7
Source/Core/Request.swift

@@ -533,7 +533,7 @@ public class Request: @unchecked Sendable {
     ///  - Note: This method will also `resume` the instance if `delegate.startImmediately` returns `true`.
     ///
     /// - Parameter closure: The closure containing the response serialization call.
-    func appendResponseSerializer(_ closure: @Sendable @escaping () -> Void) {
+    func appendResponseSerializer(_ closure: @escaping @Sendable () -> Void) {
         mutableState.write { mutableState in
             mutableState.responseSerializers.append(closure)
 
@@ -607,7 +607,7 @@ public class Request: @unchecked Sendable {
     ///
     /// - Parameter completion: The completion handler provided with the response serializer, called when all serializers
     ///                         are complete.
-    func responseSerializerDidComplete(completion: @Sendable @escaping () -> Void) {
+    func responseSerializerDidComplete(completion: @escaping @Sendable () -> Void) {
         mutableState.write { $0.responseSerializerCompletions.append(completion) }
         processNextResponseSerializer()
     }
@@ -849,7 +849,7 @@ public class Request: @unchecked Sendable {
     /// - Returns:           The instance.
     @preconcurrency
     @discardableResult
-    public func cURLDescription(on queue: DispatchQueue, calling handler: @Sendable @escaping (String) -> Void) -> Self {
+    public func cURLDescription(on queue: DispatchQueue, calling handler: @escaping @Sendable (String) -> Void) -> Self {
         mutableState.write { mutableState in
             if mutableState.requests.last != nil {
                 queue.async { handler(self.cURLDescription()) }
@@ -871,7 +871,7 @@ public class Request: @unchecked Sendable {
     /// - Returns:           The instance.
     @preconcurrency
     @discardableResult
-    public func cURLDescription(calling handler: @Sendable @escaping (String) -> Void) -> Self {
+    public func cURLDescription(calling handler: @escaping @Sendable (String) -> Void) -> Self {
         cURLDescription(on: underlyingQueue, calling: handler)
 
         return self
@@ -888,7 +888,7 @@ public class Request: @unchecked Sendable {
     /// - Returns:   The instance.
     @preconcurrency
     @discardableResult
-    public func onURLRequestCreation(on queue: DispatchQueue = .main, perform handler: @Sendable @escaping (URLRequest) -> Void) -> Self {
+    public func onURLRequestCreation(on queue: DispatchQueue = .main, perform handler: @escaping @Sendable (URLRequest) -> Void) -> Self {
         mutableState.write { state in
             if let request = state.requests.last {
                 queue.async { handler(request) }
@@ -913,7 +913,7 @@ public class Request: @unchecked Sendable {
     /// - Returns:   The instance.
     @preconcurrency
     @discardableResult
-    public func onURLSessionTaskCreation(on queue: DispatchQueue = .main, perform handler: @Sendable @escaping (URLSessionTask) -> Void) -> Self {
+    public func onURLSessionTaskCreation(on queue: DispatchQueue = .main, perform handler: @escaping @Sendable (URLSessionTask) -> Void) -> Self {
         mutableState.write { state in
             if let task = state.tasks.last {
                 queue.async { handler(task) }
@@ -1089,7 +1089,7 @@ public protocol RequestDelegate: AnyObject, Sendable {
     ///   - request:    `Request` which failed.
     ///   - error:      `Error` which produced the failure.
     ///   - completion: Closure taking the `RetryResult` for evaluation.
-    func retryResult(for request: Request, dueTo error: AFError, completion: @Sendable @escaping (RetryResult) -> Void)
+    func retryResult(for request: Request, dueTo error: AFError, completion: @escaping @Sendable (RetryResult) -> Void)
 
     /// Asynchronously retry the `Request`.
     ///

+ 3 - 3
Source/Core/Session.swift

@@ -217,7 +217,7 @@ open class Session: @unchecked Sendable {
     ///
     /// - Parameters:
     ///   - action:     Closure to perform with all `Request`s.
-    public func withAllRequests(perform action: @Sendable @escaping (Set<Request>) -> Void) {
+    public func withAllRequests(perform action: @escaping @Sendable (Set<Request>) -> Void) {
         rootQueue.async {
             action(self.activeRequests)
         }
@@ -1134,7 +1134,7 @@ open class Session: @unchecked Sendable {
 
     func performSetupOperations(for request: Request,
                                 convertible: any URLRequestConvertible,
-                                shouldCreateTask: @Sendable @escaping () -> Bool = { true }) {
+                                shouldCreateTask: @escaping @Sendable () -> Bool = { true }) {
         dispatchPrecondition(condition: .onQueue(requestQueue))
 
         let initialRequest: URLRequest
@@ -1268,7 +1268,7 @@ extension Session: RequestDelegate {
         activeRequests.remove(request)
     }
 
-    public func retryResult(for request: Request, dueTo error: AFError, completion: @Sendable @escaping (RetryResult) -> Void) {
+    public func retryResult(for request: Request, dueTo error: AFError, completion: @escaping @Sendable (RetryResult) -> Void) {
         guard let retrier = retrier(for: request) else {
             rootQueue.async { completion(.doNotRetry) }
             return

+ 9 - 9
Source/Core/WebSocketRequest.swift

@@ -72,7 +72,7 @@ import Foundation
             socket?.cancel()
         }
 
-        public func sendPing(respondingOn queue: DispatchQueue = .main, onResponse: @Sendable @escaping (PingResponse) -> Void) {
+        public func sendPing(respondingOn queue: DispatchQueue = .main, onResponse: @escaping @Sendable (PingResponse) -> Void) {
             socket?.sendPing(respondingOn: queue, onResponse: onResponse)
         }
     }
@@ -274,7 +274,7 @@ import Foundation
     }
 
     @preconcurrency
-    public func sendPing(respondingOn queue: DispatchQueue = .main, onResponse: @Sendable @escaping (PingResponse) -> Void) {
+    public func sendPing(respondingOn queue: DispatchQueue = .main, onResponse: @escaping @Sendable (PingResponse) -> Void) {
         guard isResumed else {
             queue.async { onResponse(.unsent) }
             return
@@ -375,7 +375,7 @@ import Foundation
     public func streamSerializer<Serializer>(
         _ serializer: Serializer,
         on queue: DispatchQueue = .main,
-        handler: @Sendable @escaping (_ event: Event<Serializer.Output, Serializer.Failure>) -> Void
+        handler: @escaping @Sendable (_ event: Event<Serializer.Output, Serializer.Failure>) -> Void
     ) -> Self where Serializer: WebSocketMessageSerializer, Serializer.Failure == any Error {
         forIncomingEvent(on: queue) { incomingEvent in
             let event: Event<Serializer.Output, Serializer.Failure>
@@ -405,7 +405,7 @@ import Foundation
         _ type: Value.Type = Value.self,
         on queue: DispatchQueue = .main,
         using decoder: any DataDecoder = JSONDecoder(),
-        handler: @Sendable @escaping (_ event: Event<Value, any Error>) -> Void
+        handler: @escaping @Sendable (_ event: Event<Value, any Error>) -> Void
     ) -> Self where Value: Decodable {
         streamSerializer(DecodableWebSocketMessageDecoder<Value>(decoder: decoder), on: queue, handler: handler)
     }
@@ -416,7 +416,7 @@ import Foundation
         _ type: Value.Type = Value.self,
         on queue: DispatchQueue = .main,
         using decoder: any DataDecoder = JSONDecoder(),
-        handler: @Sendable @escaping (_ value: Value) -> Void
+        handler: @escaping @Sendable (_ value: Value) -> Void
     ) -> Self where Value: Decodable & Sendable {
         streamDecodableEvents(Value.self, on: queue) { event in
             event.message.map(handler)
@@ -427,7 +427,7 @@ import Foundation
     @discardableResult
     public func streamMessageEvents(
         on queue: DispatchQueue = .main,
-        handler: @Sendable @escaping (_ event: Event<URLSessionWebSocketTask.Message, Never>) -> Void
+        handler: @escaping @Sendable (_ event: Event<URLSessionWebSocketTask.Message, Never>) -> Void
     ) -> Self {
         forIncomingEvent(on: queue) { incomingEvent in
             let event: Event<URLSessionWebSocketTask.Message, Never> = switch incomingEvent {
@@ -449,14 +449,14 @@ import Foundation
     @discardableResult
     public func streamMessages(
         on queue: DispatchQueue = .main,
-        handler: @Sendable @escaping (_ message: URLSessionWebSocketTask.Message) -> Void
+        handler: @escaping @Sendable (_ message: URLSessionWebSocketTask.Message) -> Void
     ) -> Self {
         streamMessageEvents(on: queue) { event in
             event.message.map(handler)
         }
     }
 
-    func forIncomingEvent(on queue: DispatchQueue, handler: @Sendable @escaping (IncomingEvent) -> Void) -> Self {
+    func forIncomingEvent(on queue: DispatchQueue, handler: @escaping @Sendable (IncomingEvent) -> Void) -> Self {
         socketMutableState.write { state in
             state.handlers.append((queue: queue, handler: { incomingEvent in
                 self.serializationQueue.async {
@@ -482,7 +482,7 @@ import Foundation
     @preconcurrency
     public func send(_ message: URLSessionWebSocketTask.Message,
                      queue: DispatchQueue = .main,
-                     completionHandler: @Sendable @escaping (Result<Void, any Error>) -> Void) {
+                     completionHandler: @escaping @Sendable (Result<Void, any Error>) -> Void) {
         guard !(isCancelled || isFinished) else { return }
 
         guard let socket else {

+ 1 - 1
Source/Extensions/DispatchQueue+Alamofire.swift

@@ -31,7 +31,7 @@ extension DispatchQueue {
     /// - Parameters:
     ///   - delay:   `TimeInterval` to delay execution.
     ///   - closure: Closure to execute.
-    func after(_ delay: TimeInterval, execute closure: @Sendable @escaping () -> Void) {
+    func after(_ delay: TimeInterval, execute closure: @escaping @Sendable () -> Void) {
         asyncAfter(deadline: .now() + delay, execute: closure)
     }
 }

+ 3 - 3
Source/Features/AuthenticationInterceptor.swift

@@ -81,7 +81,7 @@ public protocol Authenticator: AnyObject, Sendable {
     ///   - credential: The `Credential` to refresh.
     ///   - session:    The `Session` requiring the refresh.
     ///   - completion: The closure to be executed once the refresh is complete.
-    func refresh(_ credential: Credential, for session: Session, completion: @Sendable @escaping (Result<Credential, any Error>) -> Void)
+    func refresh(_ credential: Credential, for session: Session, completion: @escaping @Sendable (Result<Credential, any Error>) -> Void)
 
     /// Determines whether the `URLRequest` failed due to an authentication error based on the `HTTPURLResponse`.
     ///
@@ -246,7 +246,7 @@ public final class AuthenticationInterceptor<AuthenticatorType>: RequestIntercep
 
     // MARK: Adapt
 
-    public func adapt(_ urlRequest: URLRequest, for session: Session, completion: @Sendable @escaping (Result<URLRequest, any Error>) -> Void) {
+    public func adapt(_ urlRequest: URLRequest, for session: Session, completion: @escaping @Sendable (Result<URLRequest, any Error>) -> Void) {
         let adaptResult: AdaptResult = mutableState.write { mutableState in
             // Queue the adapt operation if a refresh is already in place.
             guard !mutableState.isRefreshing else {
@@ -289,7 +289,7 @@ public final class AuthenticationInterceptor<AuthenticatorType>: RequestIntercep
 
     // MARK: Retry
 
-    public func retry(_ request: Request, for session: Session, dueTo error: any Error, completion: @Sendable @escaping (RetryResult) -> Void) {
+    public func retry(_ request: Request, for session: Session, dueTo error: any Error, completion: @escaping @Sendable (RetryResult) -> Void) {
         // Do not attempt retry if there was not an original request and response from the server.
         guard let urlRequest = request.request, let response = request.response else {
             completion(.doNotRetry)

+ 2 - 2
Source/Features/Combine.swift

@@ -36,7 +36,7 @@ public struct DataResponsePublisher<Value: Sendable>: Publisher {
     public typealias Output = DataResponse<Value, AFError>
     public typealias Failure = Never
 
-    private typealias Handler = (@Sendable @escaping (_ response: DataResponse<Value, AFError>) -> Void) -> DataRequest
+    private typealias Handler = (@escaping @Sendable (_ response: DataResponse<Value, AFError>) -> Void) -> DataRequest
 
     private let request: DataRequest
     private let responseHandler: Handler
@@ -404,7 +404,7 @@ public struct DownloadResponsePublisher<Value: Sendable>: Publisher {
     public typealias Output = DownloadResponse<Value, AFError>
     public typealias Failure = Never
 
-    private typealias Handler = (@Sendable @escaping (_ response: DownloadResponse<Value, AFError>) -> Void) -> DownloadRequest
+    private typealias Handler = (@escaping @Sendable (_ response: DownloadResponse<Value, AFError>) -> Void) -> DownloadRequest
 
     private let request: DownloadRequest
     private let responseHandler: Handler

+ 5 - 5
Source/Features/Concurrency.swift

@@ -346,7 +346,7 @@ extension DataRequest {
     }
 
     private func dataTask<Value>(automaticallyCancelling shouldAutomaticallyCancel: Bool,
-                                 forResponse onResponse: @Sendable @escaping (@Sendable @escaping (DataResponse<Value, AFError>) -> Void) -> Void)
+                                 forResponse onResponse: @Sendable @escaping (@escaping @Sendable (DataResponse<Value, AFError>) -> Void) -> Void)
         -> DataTask<Value> {
         let task = Task {
             await withTaskCancellationHandler {
@@ -555,7 +555,7 @@ extension DownloadRequest {
     }
 
     private func downloadTask<Value>(automaticallyCancelling shouldAutomaticallyCancel: Bool,
-                                     forResponse onResponse: @Sendable @escaping (@Sendable @escaping (DownloadResponse<Value, AFError>) -> Void) -> Void)
+                                     forResponse onResponse: @Sendable @escaping (@escaping @Sendable (DownloadResponse<Value, AFError>) -> Void) -> Void)
         -> DownloadTask<Value> {
         let task = Task {
             await withTaskCancellationHandler {
@@ -653,7 +653,7 @@ public struct DataStreamTask: Sendable {
 
     private func createStream<Success, Failure: Error>(automaticallyCancelling shouldAutomaticallyCancel: Bool = true,
                                                        bufferingPolicy: Stream<Success, Failure>.BufferingPolicy = .unbounded,
-                                                       forResponse onResponse: @Sendable @escaping (@Sendable @escaping (DataStreamRequest.Stream<Success, Failure>) -> Void) -> Void)
+                                                       forResponse onResponse: @Sendable @escaping (@escaping @Sendable (DataStreamRequest.Stream<Success, Failure>) -> Void) -> Void)
         -> Stream<Success, Failure> {
         StreamOf(bufferingPolicy: bufferingPolicy) {
             guard shouldAutomaticallyCancel,
@@ -827,8 +827,8 @@ extension DataStreamRequest {
     private func createStream<Success, Value, Failure: Error>(
         automaticallyCancelling shouldAutomaticallyCancel: Bool,
         bufferingPolicy: StreamOf<Value>.BufferingPolicy,
-        transform: @Sendable @escaping (WebSocketRequest.Event<Success, Failure>) -> Value?,
-        forResponse onResponse: @Sendable @escaping (@Sendable @escaping (WebSocketRequest.Event<Success, Failure>) -> Void) -> Void
+        transform: @escaping @Sendable (WebSocketRequest.Event<Success, Failure>) -> Value?,
+        forResponse onResponse: @Sendable @escaping (@escaping @Sendable (WebSocketRequest.Event<Success, Failure>) -> Void) -> Void
     ) -> StreamOf<Value> {
         StreamOf(bufferingPolicy: bufferingPolicy) {
             guard shouldAutomaticallyCancel,

+ 1 - 1
Source/Features/EventMonitor.swift

@@ -321,7 +321,7 @@ public final class CompositeEventMonitor: EventMonitor {
         self.monitors = Protected(monitors)
     }
 
-    func performEvent(_ event: @Sendable @escaping (any EventMonitor) -> Void) {
+    func performEvent(_ event: @escaping @Sendable (any EventMonitor) -> Void) {
         queue.async {
             self.monitors.read { monitors in
                 for monitor in monitors {

+ 1 - 1
Source/Features/RedirectHandler.swift

@@ -105,7 +105,7 @@ extension RedirectHandler where Self == Redirector {
     ///
     /// - Parameter closure: Closure used to modify the redirect.
     /// - Returns:           The `Redirector`.
-    public static func modify(using closure: @Sendable @escaping (URLSessionTask, URLRequest, HTTPURLResponse) -> URLRequest?) -> Redirector {
+    public static func modify(using closure: @escaping @Sendable (URLSessionTask, URLRequest, HTTPURLResponse) -> URLRequest?) -> Redirector {
         Redirector(behavior: .modify(closure))
     }
 }

+ 25 - 17
Source/Features/RequestInterceptor.swift

@@ -43,7 +43,7 @@ public protocol RequestAdapter: Sendable {
     ///   - urlRequest: The `URLRequest` to adapt.
     ///   - session:    The `Session` that will execute the `URLRequest`.
     ///   - completion: The completion handler that must be called when adaptation is complete.
-    func adapt(_ urlRequest: URLRequest, for session: Session, completion: @Sendable @escaping (_ result: Result<URLRequest, any Error>) -> Void)
+    func adapt(_ urlRequest: URLRequest, for session: Session, completion: @escaping @Sendable (_ result: Result<URLRequest, any Error>) -> Void)
 
     /// Inspects and adapts the specified `URLRequest` in some manner and calls the completion handler with the Result.
     ///
@@ -51,11 +51,12 @@ public protocol RequestAdapter: Sendable {
     ///   - urlRequest: The `URLRequest` to adapt.
     ///   - state:      The `RequestAdapterState` associated with the `URLRequest`.
     ///   - completion: The completion handler that must be called when adaptation is complete.
-    func adapt(_ urlRequest: URLRequest, using state: RequestAdapterState, completion: @Sendable @escaping (_ result: Result<URLRequest, any Error>) -> Void)
+    func adapt(_ urlRequest: URLRequest, using state: RequestAdapterState, completion: @escaping @Sendable (_ result: Result<URLRequest, any Error>) -> Void)
 }
 
 extension RequestAdapter {
-    public func adapt(_ urlRequest: URLRequest, using state: RequestAdapterState, completion: @Sendable @escaping (_ result: Result<URLRequest, any Error>) -> Void) {
+    @preconcurrency
+    public func adapt(_ urlRequest: URLRequest, using state: RequestAdapterState, completion: @escaping @Sendable (_ result: Result<URLRequest, any Error>) -> Void) {
         adapt(urlRequest, for: state.session, completion: completion)
     }
 }
@@ -109,7 +110,7 @@ public protocol RequestRetrier: Sendable {
     ///   - session:    `Session` that produced the `Request`.
     ///   - error:      `Error` encountered while executing the `Request`.
     ///   - completion: Completion closure to be executed when a retry decision has been determined.
-    func retry(_ request: Request, for session: Session, dueTo error: any Error, completion: @Sendable @escaping (RetryResult) -> Void)
+    func retry(_ request: Request, for session: Session, dueTo error: any Error, completion: @escaping @Sendable (RetryResult) -> Void)
 }
 
 // MARK: -
@@ -119,7 +120,7 @@ public protocol RequestInterceptor: RequestAdapter, RequestRetrier {}
 
 extension RequestInterceptor {
     @preconcurrency
-    public func adapt(_ urlRequest: URLRequest, for session: Session, completion: @Sendable @escaping (Result<URLRequest, any Error>) -> Void) {
+    public func adapt(_ urlRequest: URLRequest, for session: Session, completion: @escaping @Sendable (Result<URLRequest, any Error>) -> Void) {
         completion(.success(urlRequest))
     }
 
@@ -127,7 +128,7 @@ extension RequestInterceptor {
     public func retry(_ request: Request,
                       for session: Session,
                       dueTo error: any Error,
-                      completion: @Sendable @escaping (RetryResult) -> Void) {
+                      completion: @escaping @Sendable (RetryResult) -> Void) {
         completion(.doNotRetry)
     }
 }
@@ -135,12 +136,13 @@ extension RequestInterceptor {
 /// `RequestAdapter` closure definition.
 public typealias AdaptHandler = @Sendable (_ request: URLRequest,
                                            _ session: Session,
-                                           _ completion: @escaping (Result<URLRequest, any Error>) -> Void) -> Void
+                                           _ completion: @escaping @Sendable (Result<URLRequest, any Error>) -> Void) -> Void
+
 /// `RequestRetrier` closure definition.
 public typealias RetryHandler = @Sendable (_ request: Request,
                                            _ session: Session,
                                            _ error: any Error,
-                                           _ completion: @escaping (RetryResult) -> Void) -> Void
+                                           _ completion: @escaping @Sendable (RetryResult) -> Void) -> Void
 
 // MARK: -
 
@@ -158,12 +160,12 @@ open class Adapter: @unchecked Sendable, RequestInterceptor {
     }
 
     @preconcurrency
-    open func adapt(_ urlRequest: URLRequest, for session: Session, completion: @escaping (Result<URLRequest, any Error>) -> Void) {
+    open func adapt(_ urlRequest: URLRequest, for session: Session, completion: @escaping @Sendable (Result<URLRequest, any Error>) -> Void) {
         adaptHandler(urlRequest, session, completion)
     }
 
     @preconcurrency
-    open func adapt(_ urlRequest: URLRequest, using state: RequestAdapterState, completion: @escaping (Result<URLRequest, any Error>) -> Void) {
+    open func adapt(_ urlRequest: URLRequest, using state: RequestAdapterState, completion: @escaping @Sendable (Result<URLRequest, any Error>) -> Void) {
         adaptHandler(urlRequest, state.session, completion)
     }
 }
@@ -173,6 +175,7 @@ extension RequestAdapter where Self == Adapter {
     ///
     /// - Parameter closure: `AdaptHandler` to use to adapt the request.
     /// - Returns:           The `Adapter`.
+    @preconcurrency
     public static func adapter(using closure: @escaping AdaptHandler) -> Adapter {
         Adapter(closure)
     }
@@ -192,10 +195,11 @@ open class Retrier: @unchecked Sendable, RequestInterceptor {
         self.retryHandler = retryHandler
     }
 
+    @preconcurrency
     open func retry(_ request: Request,
                     for session: Session,
                     dueTo error: any Error,
-                    completion: @escaping (RetryResult) -> Void) {
+                    completion: @escaping @Sendable (RetryResult) -> Void) {
         retryHandler(request, session, error, completion)
     }
 }
@@ -205,6 +209,7 @@ extension RequestRetrier where Self == Retrier {
     ///
     /// - Parameter closure: `RetryHandler` to use to retry the request.
     /// - Returns:           The `Retrier`.
+    @preconcurrency
     public static func retrier(using closure: @escaping RetryHandler) -> Retrier {
         Retrier(closure)
     }
@@ -253,14 +258,14 @@ open class Interceptor: @unchecked Sendable, RequestInterceptor {
     }
 
     @preconcurrency
-    open func adapt(_ urlRequest: URLRequest, for session: Session, completion: @Sendable @escaping (Result<URLRequest, any Error>) -> Void) {
+    open func adapt(_ urlRequest: URLRequest, for session: Session, completion: @escaping @Sendable (Result<URLRequest, any Error>) -> Void) {
         adapt(urlRequest, for: session, using: adapters, completion: completion)
     }
 
     private func adapt(_ urlRequest: URLRequest,
                        for session: Session,
                        using adapters: [any RequestAdapter],
-                       completion: @Sendable @escaping (Result<URLRequest, any Error>) -> Void) {
+                       completion: @escaping @Sendable (Result<URLRequest, any Error>) -> Void) {
         var pendingAdapters = adapters
 
         guard !pendingAdapters.isEmpty else { completion(.success(urlRequest)); return }
@@ -278,14 +283,14 @@ open class Interceptor: @unchecked Sendable, RequestInterceptor {
     }
 
     @preconcurrency
-    open func adapt(_ urlRequest: URLRequest, using state: RequestAdapterState, completion: @Sendable @escaping (Result<URLRequest, any Error>) -> Void) {
+    open func adapt(_ urlRequest: URLRequest, using state: RequestAdapterState, completion: @escaping @Sendable (Result<URLRequest, any Error>) -> Void) {
         adapt(urlRequest, using: state, adapters: adapters, completion: completion)
     }
 
     private func adapt(_ urlRequest: URLRequest,
                        using state: RequestAdapterState,
                        adapters: [any RequestAdapter],
-                       completion: @Sendable @escaping (Result<URLRequest, any Error>) -> Void) {
+                       completion: @escaping @Sendable (Result<URLRequest, any Error>) -> Void) {
         var pendingAdapters = adapters
 
         guard !pendingAdapters.isEmpty else { completion(.success(urlRequest)); return }
@@ -306,7 +311,7 @@ open class Interceptor: @unchecked Sendable, RequestInterceptor {
     open func retry(_ request: Request,
                     for session: Session,
                     dueTo error: any Error,
-                    completion: @Sendable @escaping (RetryResult) -> Void) {
+                    completion: @escaping @Sendable (RetryResult) -> Void) {
         retry(request, for: session, dueTo: error, using: retriers, completion: completion)
     }
 
@@ -314,7 +319,7 @@ open class Interceptor: @unchecked Sendable, RequestInterceptor {
                        for session: Session,
                        dueTo error: any Error,
                        using retriers: [any RequestRetrier],
-                       completion: @Sendable @escaping (RetryResult) -> Void) {
+                       completion: @escaping @Sendable (RetryResult) -> Void) {
         var pendingRetriers = retriers
 
         guard !pendingRetriers.isEmpty else { completion(.doNotRetry); return }
@@ -340,6 +345,7 @@ extension RequestInterceptor where Self == Interceptor {
     ///   - adapter: `AdapterHandler`to use to adapt the request.
     ///   - retrier: `RetryHandler` to use to retry the request.
     /// - Returns:   The `Interceptor`.
+    @preconcurrency
     public static func interceptor(adapter: @escaping AdaptHandler, retrier: @escaping RetryHandler) -> Interceptor {
         Interceptor(adaptHandler: adapter, retryHandler: retrier)
     }
@@ -349,6 +355,7 @@ extension RequestInterceptor where Self == Interceptor {
     ///   - adapter: `RequestAdapter` to use to adapt the request
     ///   - retrier: `RequestRetrier` to use to retry the request.
     /// - Returns:   The `Interceptor`.
+    @preconcurrency
     public static func interceptor(adapter: any RequestAdapter, retrier: any RequestRetrier) -> Interceptor {
         Interceptor(adapter: adapter, retrier: retrier)
     }
@@ -360,6 +367,7 @@ extension RequestInterceptor where Self == Interceptor {
     ///                   a retry is triggered.
     ///   - interceptors: `RequestInterceptor`s to use to intercept the request.
     /// - Returns:        The `Interceptor`.
+    @preconcurrency
     public static func interceptor(adapters: [any RequestAdapter] = [],
                                    retriers: [any RequestRetrier] = [],
                                    interceptors: [any RequestInterceptor] = []) -> Interceptor {

+ 2 - 2
Source/Features/URLEncodedFormEncoder.swift

@@ -306,7 +306,7 @@ public final class URLEncodedFormEncoder {
         /// Creates an instance with the encoding closure called for each sub-key in a key path.
         ///
         /// - Parameter encoding: Closure used to perform the encoding.
-        public init(encoding: @Sendable @escaping (_ subkey: String) -> String) {
+        public init(encoding: @escaping @Sendable (_ subkey: String) -> String) {
             self.encoding = encoding
         }
 
@@ -329,7 +329,7 @@ public final class URLEncodedFormEncoder {
         /// Creates an instance with the encoding closure called for `nil` values.
         ///
         /// - Parameter encoding: Closure used to perform the encoding.
-        public init(encoding: @Sendable @escaping () -> String?) {
+        public init(encoding: @escaping @Sendable () -> String?) {
             self.encoding = encoding
         }