URL Session Interceptor
URL Interception allows you to create a URLSession, the tasks of which can be intercepted and reacted to as you would do for a normal Task
when used with the TaskManager
See URLInterceptor
-
This is URLSession wrapper that provides interception and reaction funcitonality. The ideas behind the URLTaskManager is to be able to control URLSession tasks at a more fine grained level, and to have a automatic mechanism to re-fire them should the need arise.
This is done by setting a URLProtocol on the URLSession object that is exposed to the client. Therefore, the URLSessionConfiguration object that you pass in to the URLTaskManager object will have its
protocolClasses
member changed.One example of a use case is to be able to do OAuth2 refresh operations. Should a task come back with a 401 status code, a reactor can perform a refresh operation, reset the any user state to include the new authorization and refresh token, and the requeue the task.
Another use case if you want to enrich a URL tasks with headers, or if you want to batch url requests and release them in one go.
Intercepting tasks
Every request that is sent through
URLTaskManager.session
is run through any associatedURLTaskInterceor
s orURLTaskReactor
s as aURLTask
object that contain an accessibleURLRequest
object.class Interceptor: URLTaskInterceptor { let user: User init(user: User) { self.user = user } func intercept(task: inout URLTask, currentBatchCount _: Int) -> InterceptCommand { // Add a field to the request before it's fired off task.request.addValue(self.user.authorization, forHTTPHeaderField: "Authorization") return .execute } }
Reacting to tasks
The same principles apply as with intercepting tasks. To react to a a
URLTask
object you may implement aURLTaskReactor
object.
See moreclass Reactor: URLTaskReactor { let user: User init(user: User) { self.user = user } func execute(done: @escaping (Error?) -> Void) { // For example one could refresh the authorization tokens here user.refreshAuthorizationToken { result in switch result { case .success: done(nil) case let .failure(value): done(value) } } func shouldExecute<T: Task>(after result: URLTask.Result, from task: URLTask, with _: Handle) -> Bool { if case let .success(value) = result { return value.(response as? HTTPURLResponse)?.statusCode == 401 } return false } }
Declaration
Swift
public class URLTaskManager
-
This is the
See moreTask
object that is used byURLTaskManager
. This is the type of theTask
object that would be passed in toURLTaskInterceptor.intercept(...)
andURLTaskReactor.shouldExecute(...)
when using theURLTaskManager
.Declaration
Swift
public class URLTask : Task
-
This protocol provides a means to intercept
URLTask
s.You only need to implement the specialized
See moreintercept
function in this protocol. The protocol has default conformance toInterceptor
.Declaration
Swift
public protocol URLTaskInterceptor : Interceptor
-
Errors that happen internally in the URLTaskManager
See moreDeclaration
Swift
public enum URLTaskManagerError : Error