URLTaskManager
public class URLTaskManager
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 associated URLTaskInterceor
s or
URLTaskReactor
s as a URLTask
object that contain an accessible URLRequest
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 a URLTaskReactor
object.
class 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
}
}
-
And tasks executed through this URLSession can be intercetped and reacted to.
Declaration
Swift
public let session: URLSession
-
Creates a URLTaskManager object
Declaration
Swift
public init(interceptors: [URLTaskInterceptor] = [], reactors: [URLTaskReactor] = [], configuration: URLSessionConfiguration = .default)
Parameters
interceptors
list of interceptors that will be run before each URLSessionTask is executed
rectors
list of reactors that will run upon completion of the URLSessionTask
configuration
passed on to the URLSession object