iraxef
iraxef

Reputation: 665

Modify headers on Alamofire request before it is resume()d

I am creating Alamofire requests with startRequestsImmediately set to false. I then enqueue a block onto an NSOperationQueue which calls resume() on the request. If I need to suspend outgoing requests, I simply suspend the queue and let them buffer up. Once I unsuspend the queue, any requests are dispatched.

Sometimes, while the queue is suspended, I need to change a header on any existing requests in there (e.g. an authorization token). I have not found a way to do this (anything I try isn't taking effect). Is it possible with NSURLSessionTask? Is it possible to swap out the NSURLSessionTask for a given request (with updated headers)?

Upvotes: 3

Views: 1040

Answers (1)

iraxef
iraxef

Reputation: 665

As soon as the Alamofire.Request is created, it creates an NSURLSessionTask under the hood and once created, that is effectively read-only. So the only option I've found is to defer creation of the Request until my request is about to be run.

However, the Request object is what you set up response handlers on. For example, the client wants to call something like: request().response(...).response(...). Alamofire's request() returns the Request object on which you can call response() multiple times in order to setup the response handlers which will run once the request is finished. But if you need to defer the creation of the Request until you know it's about to run - so that you can use the latest headers at that time - how do you return it to the clients so that they can call .response() on it?

The way I've done it is to create a myRequest() wrapper (instead of being able to override the actual request() function/name) on my Alamofire.Manager-derived class, which takes 1 additional parameter - a 'request ready' block (which itself takes an Alamofire.Request) and instead of returning the Request from myRequest(), myRequest(), returns nothing, but calls the block (passing it the Request) just as the request is about to be dispatched.

So something like

manager.request(.GET, "endpoint").responseJSON(…)

instead becomes

manager.myRequest(.GET, "endpoint") { request in
    request.responseJSON(...)
}

In this way I can defer creation of the Alamofire.Request (which immediately creates the underlying NSURLSessionTask and locks in the headers as they are at that moment) until later, while not inconveniencing the client too much in how they specify the response handlers.

myRequest() looks like this (not including app-specific stuff):

func myRequest(
    method: Alamofire.Method,
    _ URLString: URLStringConvertible,
    parameters: [String: AnyObject]? = nil,
    encoding: ParameterEncoding = .URL,
    headers: [String: String]? = nil,
    requestReady: ((Request) -> Void)?) {

    pendingRequestsQueue.addOperationWithBlock { [weak self] in
        if let strongSelf = self {
            let request = strongSelf.request(method, URLString, parameters: parameters, encoding: encoding, headers: headers)

            if let requestReady = requestReady {
                requestReady(request)
            }

            request.resume()
        }
    }
}

Upvotes: 2

Related Questions