Set timeout in Alamofire
Asked Answered
S

16

67

I am using Alamofire 4.0.1 and I want to set a timeout for my request. I tried the solutions gived in this question:

In the first case, it throws a NSURLErrorDomain (timeout is set correctly):

let configuration = URLSessionConfiguration.default
configuration.timeoutIntervalForRequest = 10

    let sessionManager = Alamofire.SessionManager(configuration: configuration)
    sessionManager.request("yourUrl", method: .post, parameters: ["parameterKey": "value"])
            .responseJSON {
                response in
                switch (response.result) {
                case .success:
                    //do json stuff
                    break
                case .failure(let error):
                    if error._code == NSURLErrorTimedOut {
                        //timeout here
                    }
                    print("\n\nAuth request failed with error:\n \(error)")
                    break
                }
            }

In the second case, the time out is not replaced and still set as 60 seconds.

let manager = Alamofire.SessionManager.default
manager.session.configuration.timeoutIntervalForRequest = 10

manager.request("yourUrl", method: .post, parameters: ["parameterKey": "value"])

I am running in ios 10.1

My code: (it doesn't work)

    let configuration = URLSessionConfiguration.default
    configuration.timeoutIntervalForRequest = 10 // seconds
    configuration.timeoutIntervalForResource = 10
    let alamoFireManager = Alamofire.SessionManager(configuration: configuration)

    alamoFireManager.request("my_url", method: .post, parameters: parameters).responseJSON { response in


        switch (response.result) {
        case .success:
                 //Success....
            break
        case .failure(let error):
            // failure...
            break
        }
    }

Solved Alamofire github thread: Alamofire 4.3.0 setting timeout throws NSURLErrorDomain error #1931

Songful answered 23/1, 2017 at 10:15 Comment(2)
you are setting Request Time Out , set Resource Timeout instead. timeoutIntervalForResourceAdulate
it seems doesn't work, I updated with my actual code.Ician
S
10

Based in @kamal-thakur response.

Swift 3:

var request = URLRequest(url: NSURL.init(string: "YOUR_URL") as! URL)
request.httpMethod = "POST"
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.timeoutInterval = 10 // 10 secs
let postString = "param1=\(var1)&param2=\(var2)"
request.httpBody = postString.data(using: .utf8)
Alamofire.request(request).responseJSON {
    response in
    // do whatever you want here
}
Songful answered 1/6, 2017 at 7:16 Comment(0)
C
40

Alamofire 5.1 includes a new way to modify the request with a closure in the initializer:

AF.request(url) { $0.timeoutInterval = 60 }
    .validate()
    .response { _ in // handle response here }
Commodity answered 13/4, 2020 at 16:34 Comment(1)
To be honest, Alamofire gives too much flexibility on declaring certain things which leads to confusion. Those kind of settings better be restricted to Session. Imagine each developers starts setting their own time out interval on their newly developed API. This can be prevented by creating one more layer of Proxy (or wrapper) around Alamofire to execute requests but still add verbosity for no reason.Thielen
D
36

For new versions of AF, see https://mcmap.net/q/293548/-set-timeout-in-alamofire


For old versions, please try this:

    let request = NSMutableURLRequest(url: URL(string: "")!)
    request.httpMethod = "POST"
    request.setValue("application/json", forHTTPHeaderField: "Content-Type")
    request.timeoutInterval = 10 // 10 secs
    let values = ["key": "value"]
    request.httpBody = try! JSONSerialization.data(withJSONObject: values, options: [])
    Alamofire.request(request as! URLRequestConvertible).responseJSON {
        response in
        // do whatever you want here
    }
Diena answered 24/1, 2017 at 8:16 Comment(3)
hmm i seem to get this error: Could not cast value of type 'NSMutableURLRequest' to 'Alamofire.URLRequestConvertible'.Hesperidium
try 'var request = URLRequest(url: url)' instead of 'let request = NSMutableURLRequest(url: url)'Estival
Works like a champ!!Merriott
F
28

I have same problem too, I think I found the solution. Try to declare SessionManager?or in your case alamofireManager in class, outside the function

class ViewController: UIViewController {
   var alamoFireManager : SessionManager? // this line

   func alamofire(){
        let configuration = URLSessionConfiguration.default
        configuration.timeoutIntervalForRequest = 10
        configuration.timeoutIntervalForResource = 10
        alamoFireManager = Alamofire.SessionManager(configuration: configuration) // not in this line

        alamoFireManager.request("my_url", method: .post, parameters: parameters).responseJSON { response in


        switch (response.result) {
        case .success:
                 //Success....
            break
        case .failure(let error):
               // failure...
             break
       }
     }
   }

}
Farreaching answered 6/7, 2017 at 14:41 Comment(2)
Try to declare SessionManager?or in your case alamofireManager in class, outside the function <- this is the main point!!Overseas
You save my day bro. The best answer (Y).Arsenault
K
15

If you are using one instance of Alamofire, you can make a lazy var like this:

   private lazy var alamoFireManager: SessionManager? = {
    let configuration = URLSessionConfiguration.default
    configuration.timeoutIntervalForRequest = 5
    configuration.timeoutIntervalForResource = 5
    let alamoFireManager = Alamofire.SessionManager(configuration: configuration)
    return alamoFireManager

}()

Works on Swift 4.2

Kellby answered 2/4, 2019 at 9:44 Comment(0)
P
14

Try this:

    let configuration = NSURLSessionConfiguration.defaultSessionConfiguration()
    configuration.timeoutIntervalForRequest = 4 // seconds
    configuration.timeoutIntervalForResource = 4
    self.alamoFireManager = Alamofire.Manager(configuration: configuration)

Swift 3.0

    let configuration = URLSessionConfiguration.default
    configuration.timeoutIntervalForRequest = 4 // seconds
    configuration.timeoutIntervalForResource = 4
    self.alamoFireManager = Alamofire.SessionManager(configuration: configuration)
Painkiller answered 23/1, 2017 at 10:25 Comment(3)
Same result than the first case.Ician
@ƒernandoValle Instead of editing other peoples answers you should incorporate the changes into your question or create an own asnwer.Handspike
@LotPings I updated my question and I updated this code because is easy for check if there is any error.Ician
M
10

As Matt said the problem is the following

The difference here is that the initialized manager is not owned, and is deallocated shortly after it goes out of scope. As a result, any pending tasks are cancelled.

The solution to this problem was written by rainypixels

import Foundation import Alamofire

class NetworkManager {

    var manager: Manager?

    init() {
        let configuration = NSURLSessionConfiguration.defaultSessionConfiguration()
        manager = Alamofire.Manager(configuration: configuration)
    }
}

And my own version

class APIManager {

    private var sessionManager = Alamofire.SessionManager()

    func requestCards(_ days_range: Int, success: ((_ cards: [CardModel]) -> Void)?, fail: ((_ error: Error) -> Void)?) {
        DispatchQueue.global(qos: .background).async {
            let parameters = ["example" : 1]

            let headers = ["AUTH" : "Example"]

            let configuration = URLSessionConfiguration.default
            configuration.timeoutIntervalForRequest = 10
            self.sessionManager = Alamofire.SessionManager(configuration: configuration)

            self.sessionManager.request(URLs.cards.value, method: .get, parameters: parameters, encoding: URLEncoding.default, headers: headers).responseJSON { (response) in
                switch response.result {
                case .success:
                    //do json stuff
                    guard let json = response.result.value as? [String : Any] else { return }
                    guard let result = json["result"] as? [[String : Any]] else { return }
                    let cards = Mapper<CardModel>().mapArray(JSONArray: result)
                    debugPrint("cards", cards.count)
                    success?(cards)
                case .failure(let error):
                    if error._code == NSURLErrorTimedOut {
                        //timeout here
                        debugPrint("timeOut")
                    }
                    debugPrint("\n\ncard request failed with error:\n \(error)")
                    fail?(error)
                }
            }
        }
    }
}

Can also make a manager for it

import Alamofire

struct AlamofireAppManager {

    static let shared: SessionManager = {
        let configuration = URLSessionConfiguration.default
        configuration.timeoutIntervalForRequest = 10
        let sessionManager = Alamofire.SessionManager(configuration: configuration)
        return sessionManager
    }()

}
Medlock answered 1/6, 2017 at 3:30 Comment(0)
S
10

Based in @kamal-thakur response.

Swift 3:

var request = URLRequest(url: NSURL.init(string: "YOUR_URL") as! URL)
request.httpMethod = "POST"
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.timeoutInterval = 10 // 10 secs
let postString = "param1=\(var1)&param2=\(var2)"
request.httpBody = postString.data(using: .utf8)
Alamofire.request(request).responseJSON {
    response in
    // do whatever you want here
}
Songful answered 1/6, 2017 at 7:16 Comment(0)
M
7

Based on Letaief Achraf's answer, but for Swift 5.0 and Alamofire pod version >= 5.0.0

//MARK: - Session Manager
private static var alamofireManager: Session? = {
    let configuration = URLSessionConfiguration.default
    configuration.timeoutIntervalForRequest = 10
    let alamofireManager = Session(configuration: configuration)
    return alamofireManager
}()

Use this variable inside an APIManager or something similar.

Mimosa answered 8/4, 2020 at 9:53 Comment(0)
K
5

In Swift 5. You can do in this way.

AF.sessionConfiguration.timeoutIntervalForRequest = 60
Kauslick answered 18/7, 2020 at 5:52 Comment(0)
E
4

Based on the latest release 5.4.4, you can set the time out like this:

AF.request("https://stackoverflow.com", requestModifier: { $0.timeoutInterval = 5 }).response(...)

Here's the documentation.

Example:

let url = URL(string: "https://stackoverflow.com")

AF.request(url, method: .get, requestModifier: { $0.timeoutInterval = .infinity }).validate().responseData { response in
    // Do something with the response ...
}
Embrasure answered 13/10, 2021 at 23:1 Comment(0)
D
2

after a lot of try I made it whit the next:

var timeout = 300 // 5 minutes

//Post values
    let parameters:Parameters = parameters

    //Server value
    let url:URL = (url)


    //Make the request
    let configuration = URLSessionConfiguration.default
    configuration.timeoutIntervalForResource = TimeInterval(timeout)
    configuration.timeoutIntervalForRequest = TimeInterval(timeout)

    let sessionManager = Alamofire.SessionManager(configuration: configuration)

     sessionManager.request(url,parameters:parameters).validate(statusCode: 200..<300).responseJSON { response in


        print(response.request)  // original URL request
        print(response.response) // URL response

        print(sessionManager.session.configuration.timeoutIntervalForRequest)   // result of response time
        print(response.timeline.totalDuration)


        switch response.result {
        case .success:

            if let valJSON = response.result.value {


               //use your json result 



            }

        case .failure (let error):

            print("\n\nAuth request failed with error:\n \(error)")

        }
    }

I hope it helps ;)

Dissentient answered 15/5, 2017 at 23:27 Comment(1)
What's the difference between your response and Jason's? https://mcmap.net/q/293548/-set-timeout-in-alamofireGeneticist
D
1

It's works for me:

let url:String = "http://..."
let request = URLRequest(url: url)
request.httpMethod = "POST"
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.addValue("Kirk Hamet", forHTTPHeaderField:"name")
request.timeoutInterval = 23 //Second

Alamofire.request(request).responseJSON {
                response in
    if response.result.isSuccess == true {

    }else{

    }

}

Swift 4.1

Delano answered 31/7, 2018 at 8:50 Comment(0)
T
1

If you don't want to build a UrlRequest yourself, you can still use Alamofire to build it.

    // set this flag to false so the request will not be sent until
    // resume() is called
    sessionManager.startRequestsImmediately = false

    var urlRequest = sessionManager.request(url,
                                            method: method,
                                            parameters: params,
                                            encoding: encoding,
                                            headers: allHeaders).request!

    urlRequest.timeoutInterval = 10

    let request = sessionManager.request(urlRequest).responseJSON { (result) in
        // use the result
    }

    // need to start the request
    request.resume()
Tally answered 5/3, 2019 at 23:31 Comment(0)
H
1

None of the above worked for me: Im on swift 4.2 Alamofire 4.5

I managed to solve it like this :

let request = Alamofire.request("routee", method: .post, parameters: data, encoding: JSONEncoding.default, headers: getHeaders())

/// getting request created by Alamofire and then updating its timeout Value

let url = URL(string: "myroute")!
        var request = try URLRequest(url: url, method: method, headers: headers)
        request.timeoutInterval = 900 // timeout
        request = try JSONEncoding.default.encode(request, with: data)

Alamofire.request(request)
    .responseJSON { response in

}
Hansel answered 22/3, 2019 at 9:41 Comment(0)
D
0

i have code for swift 2.3 hope it helps you, try it

    let configuration = NSURLSessionConfiguration.defaultSessionConfiguration()
    configuration.timeoutIntervalForResource = 10800 // seconds
    configuration.timeoutIntervalForRequest = 10800 // seconds

    alamoFireManager = Alamofire.Manager(configuration: configuration)
David answered 23/1, 2017 at 10:25 Comment(2)
Same result than the first case.Ician
take var alamoFireManager : Alamofire.Manager! as globallyDavid
M
0
//MARK:- Working sessionManger
private static var sessionManger: Session? = {
    let configuration = URLSessionConfiguration.default
    configuration.timeoutIntervalForRequest = TimeInterval(timeOut)
    configuration.httpShouldUsePipelining = true
    let sessionManager = Session(configuration: configuration, startRequestsImmediately: true)
    return sessionManager
}()
Menswear answered 3/11, 2022 at 4:45 Comment(1)
This one is working try this oneMenswear

© 2022 - 2024 — McMap. All rights reserved.