Search code examples
iosswiftxcodehttprequestalamofire

Save and resend Alamofire request


I am using Alamofire and I want to send a get request. If this fails, I want to retry it again after some other operations.

I save the request in a variable:

let myRequest = Alamofire.request("myurl", method: .get)

and in another function:

func retry(request:DataRequest) {
   request.responseSwiftyJSON { response in
      // ... code to handle the response ...
   }
}

In this way, I can call multiple times the retry function, passing the same object myRequest.

However, the request is sent correctly only the first time, then I think it is cached (or in some way the Alamofire object realizes that the response field of the request object is already valid) and the request is not sent again to the server.

To solve this problem, I tried to change a little bit the retry function in this way:

func retry2(request:DataRequest) {
   Alamofire.request(request.request!).responseSwiftyJSON { response in
      // ... code to handle the response ...
   }
}

This should initialize a new Alamofire request using only the URLRequest field of the saved request, but now the request is called twice every time! (I check it in my backend and I am sure this is caused by using this approach).

Is there any way to resend the original saved request? Does Alamofire have some way to initialize a new request from a saved one?

Solution

I ended up by doing something like @JonShier and @DuncanC suggested me:

struct APIRequest {

let url: URLConvertible
let method: HTTPMethod
let parameters: Parameters?
let encoding: ParameterEncoding
let headers: HTTPHeaders?

init(_ url:URLConvertible, method:HTTPMethod = .get, parameters:Parameters? = nil, encoding:ParameterEncoding =  URLEncoding.default, headers:HTTPHeaders? = nil) {
    self.url = url
    self.method = method
    self.parameters = parameters
    self.encoding = encoding
    self.headers = headers
}

func make() -> DataRequest {
    return Alamofire.request(url, method: method, parameters: parameters, encoding: encoding, headers: headers)
}

}

Solution

  • I haven't used AlamoFire much, and that minimal use was a couple of years ago.

    Looking around in the AlamoFire code, it appears that the request() function returns a DataRequest object. Further, it looks like a DataRequest is a reference type that is meant to track a specific request to a server and it's responses.

    It looks to make like once you create one, you use it until it completes or fails, and then discard it. They do not appear to be intended to be reused for subsequent requests of the same type.

    To summarize:

    Question: "How do I reuse AlamoFire DataRequest objects."
    Answer: "Don't do that."