Is it possible to add timeout handler for Alamofire request?
In my project I use Alamofire this way:
init() {
let configuration = NSURLSessionConfiguration.defaultSessionConfiguration()
configuration.timeoutIntervalForRequest = 30
self.alamofireManager = Alamofire.Manager(configuration: configuration)
}
func requestAuthorizationWithEmail(email:NSString, password:NSString, completion: (result: RequestResult) -> Void) {
self.alamofireManager!.request(.POST, "myURL", parameters:["email": email, "password":password])
.responseJSON { response in
switch response.result {
case .Success(let JSON):
//do json stuff
case .Failure(let error):
print("\n\nAuth request failed with error:\n \(error)")
completion(result: .ConnectionFailed)
}
}
}
EDIT:
request fail message
Error Domain=NSURLErrorDomain Code=-1001 "The request timed out." UserInfo={NSUnderlyingError=0x7fc10b937320 {Error Domain=kCFErrorDomainCFNetwork Code=-1001 "(null)" UserInfo={_kCFStreamErrorCodeKey=-2102, _kCFStreamErrorDomainKey=4}}, NSErrorFailingURLStringKey=url, NSErrorFailingURLKey=url, _kCFStreamErrorDomainKey=4, _kCFStreamErrorCodeKey=-2102, NSLocalizedDescription=The request timed out.}
You can compare error._code
and if it is equal to -1001
which is NSURLErrorTimedOut
then you know this was a timeout.
let manager = Alamofire.SessionManager.default
manager.session.configuration.timeoutIntervalForRequest = 120
manager.request("yourUrl", method: .post, parameters: ["parameterKey": "value"])
.responseJSON {
response in
switch (response.result) {
case .success: // succes path
case .failure(let error):
if error._code == NSURLErrorTimedOut {
print("Request timeout!")
}
}
}
Swift 3
The accepted answer didn't work for me.
After a lot of research, I did it like this:
let manager = Alamofire.SessionManager.default
manager.session.configuration.timeoutIntervalForRequest = 120
manager.request("yourUrl", method: .post, parameters: ["parameterKey": "value"])
I wanted to set the same timeout for every HTTP call in my project.
The key idea is to declare the Alamofire Session Manager as a global variable. Then to create a URLSessionConfiguration variable, set its timeout in seconds and assign it to the manager.
Every call in the project can use this configured session manager.
In my case the global Alamofire Session Manager variable was set in AppDelegate file (globally) and its configuration was managed in its didFinishLaunchingWithOptions method
AppDelegate.swift
import UIKit
var AFManager = SessionManager()
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
let configuration = URLSessionConfiguration.default
configuration.timeoutIntervalForRequest = 4 // seconds
configuration.timeoutIntervalForResource = 4 //seconds
AFManager = Alamofire.SessionManager(configuration: configuration)
return true
}
...
}
From now the Alamofire request function can be called from any part of the app using the afManager.
For example:
AFManager.request("yourURL", method: .post, parameters: parameters, encoding: JSONEncoding.default).validate().responseJSON { response in
...
}
Swift 3.x
class NetworkHelper {
static let shared = NetworkHelper()
var manager: SessionManager {
let manager = Alamofire.SessionManager.default
manager.session.configuration.timeoutIntervalForRequest = 10
return manager
}
func postJSONData( withParams parameters: Dictionary<String, Any>, toUrl urlString: String, completion: @escaping (_ error: Error,_ responseBody: Dictionary<String, AnyObject>?)->()) {
manager.request(urlString, method: .post, parameters: parameters, encoding: JSONEncoding.default).responseJSON { response in
if let error = response.result.error {
if error._code == NSURLErrorTimedOut {
print("Time out occurs!")
}
}
}
}
}
Swift 5, Alamofire 5
The cleanest way I found, that works with the latest version of Alamofire is the following:
AF.request(url).response { (dataResponse: AFDataResponse<Data?>) in
switch dataResponse.result {
case .success(let data):
// succes path
case .failure(let error):
switch error {
case .sessionTaskFailed(URLError.timedOut):
print("Request timeout!")
default:
print("Other error!")
}
}
}
Swift 3.x
Accepted answer didn't worked for me too.
This work for me!
let url = URL(string: "yourStringUrl")!
var urlRequest = URLRequest(url: url)
urlRequest.timeoutInterval = 5 // or what you want
And after:
Alamofire.request(urlRequest).response(completionHandler: { (response) in
/// code here
}
Swift 4
This my way and timeout feature is workable, meanwhile practices singleton for api class. reference from here
struct AlamofireManager {
static let shared: SessionManager = {
let configuration = URLSessionConfiguration.default
configuration.timeoutIntervalForRequest = 5
let sessionManager = Alamofire.SessionManager(configuration: configuration, delegate: SessionDelegate(), serverTrustPolicyManager: nil)
return sessionManager
}()
}
class Auth {
static let api = Auth()
private init() {}
func headers() -> HTTPHeaders {
return [
"Accept": "XXX",
"Authorization": "XXX",
"Content-Type": "XXX"
]
}
func querySample() {
AlamofireManager.shared.request("api_post_url", method: .post, parameters: ["parametersKey": "value"], encoding: JSONEncoding.default, headers: headers())
.responseJSON(queue: DispatchQueue.global(), options: []) { (response) in
switch response.result {
case .success(let value):
// do your statement
case .failure(let error):
if error._code == NSURLErrorTimedOut {
// timeout error statement
} else {
// other error statement
}
}
})
}
func queryOtherSample() {
AlamofireManager.shared.request("api_get_url", method: .get, parameters: nil, encoding: JSONEncoding.default, headers: headers())
.responseJSON(queue: DispatchQueue.global(), options: []) { (response) in
switch response.result {
case .success(let value):
// do your statement
case .failure(let error):
if error._code == NSURLErrorTimedOut {
// timeout error statement
} else {
// other error statement
}
}
})
}
}
For Swift 3.x / Swift 4.0 / Swift 5.0 users with Alamofire >= 5.0
Used request modifier to increase and decrease the timeout interval.
Alamofire's request creation methods offer the most common parameters for customization but sometimes those just aren't enough. The URLRequests created from the passed values can be modified by using a RequestModifier closure when creating requests. For example, to set the URLRequest's timeoutInterval to 120 seconds, modify the request in the closure.
var manager = Session.default
manager.request(urlString, method: method, parameters: dict, headers: headers, requestModifier: { $0.timeoutInterval = 120 }).validate().responseJSON { response in
OR
RequestModifiers also work with trailing closure syntax.
var manager = Session.default
manager.request("https://httpbin.org/get") { urlRequest in
urlRequest.timeoutInterval = 60
urlRequest.allowsConstrainedNetworkAccess = false
}
.response(...)
You can also check it here
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With