Fogmeister
Fogmeister

Reputation: 77641

Intercepting EVERY response with Alamofire

I'm just exploring using Alamofire and it is excellent but I'd like to do something that I feel is possible just not sure how.

Our authentication with the server uses one-time-use bearer tokens. So for every request made I have to store the new token sent down with that request.

What I'd like to do is intercept every response that comes back and check the Authorisation header. Save it to disk and then forward to the place waiting for the actual data.

Is this possible with Alamofire?

If so, please could you point me in the right direction.

Thanks

Upvotes: 7

Views: 5306

Answers (2)

Fogmeister
Fogmeister

Reputation: 77641

OK, after a bit of searching the github and head scratching I decided to create a new response serialiser by extending the Request type.

I created a new saveAuth() block like so...

extension Request {
    public static func AuthSaver() -> ResponseSerializer<Bool, NSError> {
        return ResponseSerializer { request, response, data, error in
            guard error == nil else { return .Failure(error!) }

            if let auth = response?.allHeaderFields["Authorization"] as? String {
                Router.OAuthToken = auth // this uses a didset on the Router to save to keychain
            }

            return .Success(true)
        }
    }

    public func saveAuth() -> Self {
        return response(responseSerializer: Request.AuthSaver()) {_ in}
    }
}

I can call it like...

Alamofire.request(Router.Search(query: query))
    .validate()
    .responseSaveAuth() // this line
    .responseJSON {
        response in
        // ...
}

It still requires adding in each place that I want to strip out the newly sent auth token but it means I can choose when not to do it also and it's a single line of code.

It's maybe not the most elegant code in the extension (I'm still getting to grips with it all) but it makes it much easier to save the authentication each time.

Upvotes: 7

Richmond Watkins
Richmond Watkins

Reputation: 1370

I have solved this by only having one place in my app that sends network requests. Basically, I have a "network manager" that builds up NSURLRequests and pipes them to one function that actually sends the request (in my case it's an NSOperation sub class). That way I have only one location that I'm reading responses from.

Upvotes: 2

Related Questions