Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Alamofire validate headers before receiving all data (Full body)

Using Alamofire, is it possible to have a function to handle the header response before downloading the complete file?

For example:

Our app uses the same elements on multiple pages. These elements are collected using request. Each request has his own hash (md5 checksum). We are sending this hash in the headers & i want to abort the request if the hash is recognised in the cache system.

Example implementation

APIManager.sharedManager.request(url, method: method, parameters: parameters)

            .doSomethingHere {
             //I want to read the headers here, before the data is fetched from the server.
             //There needs to be an option here to cancel the request.
            }

            .responseJSON { response in
             //If the request isn't cancel in the function above. The data should be here.
            }
}

Edit: Solution (Alamofire implementation SWIFT 3)

APIManager.sharedManager.delegate.dataTaskDidReceiveResponse =
        {(session:URLSession, dataTask:URLSessionDataTask, response:URLResponse) -> URLSession.ResponseDisposition in

            if let httpResponse = response as? HTTPURLResponse {
                //Do something with headers here. If you don't want to continue the request:
                return URLSession.ResponseDisposition.cancel

            }       

            return URLSession.ResponseDisposition.allow
    }

APIManager.sharedManager.request(url, method: method, parameters: parameters)
                .responseJSON { response in
                 //Response contains no data if it was canceled. 
                }
    }
like image 293
Bas Avatar asked Oct 04 '17 13:10

Bas


1 Answers

The header is in-fact a part of the response so you may have to make two requests in order to do this.

I gather from the comments that this is something you like to avoid. In this case what you could do is send the hash in the request itself. The server then decides whether or not to return the data.

To simplify :

  1. Send the hash in the request.
  2. The server checks if the hash exists
  3. Empty response (or some status code) if it does, response with data if it doesn't.

EDIT :

There's a better solution though... You can use the urlSession(_:dataTask:didReceive:completionHandler:) method of the URLSessionDataDelegate.

You can check the hash returned in the header. Then just pass a constant in the completion handler of this method indicating whether to continue with the task or cancel it. More on that here.

EDIT 2:

There is yet another solution using HTTP/2 Server Push protocol, although it's pretty much unchartered territory for now since it hasn't been applied in this way yet.

With server push the server sends "push promises" along with the first response. These promises are small frames that inform the client about subsequent responses that the server will send. So, in this case, you could return the hash as the first response and a push promise for the actual data.

Further reading :

  • WWDC Session
  • Server Push and Promises
  • Server Push (Stack Overflow)
  • Server Push in iOS 10 (Stack Overflow)
like image 154
NSAdi Avatar answered Oct 08 '22 10:10

NSAdi