1

We have an application which relies on network calls from the server.

There is a case (I cannot replicate it) where when the app comes to foreground from the background the network call which was in process before the app went to background times-out. It is the only time which a network call will fail.

Does anyone has an idea why this is happening?

Alamofire Configuration + Request:

let configuration = URLSessionConfiguration.default
    configuration.timeoutIntervalForRequest = 7 // seconds
    AFManager = Alamofire.SessionManager(configuration: configuration)

AFManager.request(url, method: .post, parameters: parameters, encoding: JSONEncoding.default).validate().responseString { response in
        if response.result.isSuccess {
            print(response)
            completion()
        } else {
            print(response.error!)
            completion()

        }
    }
George Vardikos
  • 2,345
  • 1
  • 14
  • 25
  • 1
    I see this with AFNetworking and obj-c when I do long polling. The fix is to start a background task when moving in to the background to complete any outstanding requests. You'll have up to about 3 minutes to complete. – FryAnEgg Sep 10 '18 at 16:12
  • @FryAnEgg I do it in a background process and the network call is small, normally takes 1 sec or so to get a response. – George Vardikos Sep 10 '18 at 18:30
  • a background task is different than a bg process or thread. Check out: https://stackoverflow.com/questions/46567311/cant-start-beginbackgroundtask-swift-3 for code and discussion – FryAnEgg Sep 10 '18 at 19:57
  • @FryAnEgg I see what you mean, but i do not do any long polling. Also in your solution how did you know which request was executing at the time the user enters the app in background? – George Vardikos Sep 11 '18 at 09:13

1 Answers1

0

I have resolved this problem with RequestRetrier from Alamofire and function

func retry(_ request: Request,
           for session: Session,
           dueTo error: Error,
           completion: @escaping (RetryResult) -> Void) {
    guard let response = request.task?.response as? HTTPURLResponse else {
        if let index = self.retryingRequests.firstIndex(of: request) {
            self.retryingRequests.remove(at: index)
            return completion(.doNotRetryWithError(error))
        }

        self.retryingRequests.append(request)
        return completion(.retry)
    }


    // Other code for refreshing Auth token

When app comes from background, the request will fail, and you will retry it. To avoid infinite loop you need to track your request that have beed already retried.

Bojan Bosanac
  • 367
  • 1
  • 13