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 associated URLTaskInterceors or URLTaskReactors 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
      }
    }
    
    See more

    Declaration

    Swift

    public class URLTaskManager
  • This is the Task object that is used by URLTaskManager. This is the type of the Task object that would be passed in to URLTaskInterceptor.intercept(...) and URLTaskReactor.shouldExecute(...) when using the URLTaskManager.

    See more

    Declaration

    Swift

    public class URLTask : Task
  • This protocol provides a means to intercept URLTasks.

    You only need to implement the specialized intercept function in this protocol. The protocol has default conformance to Interceptor.

    See more

    Declaration

    Swift

    public protocol URLTaskInterceptor : Interceptor
  • This protocol provides the means to react to a URLTask object.

    It also inherits from the Reactor protocol.

    See more

    Declaration

    Swift

    public protocol URLTaskReactor : Reactor
  • Errors that happen internally in the URLTaskManager

    See more

    Declaration

    Swift

    public enum URLTaskManagerError : Error