Handle timeout with Alamofire

后端 未结 9 1647
暗喜
暗喜 2020-12-01 05:24

Is it possible to add timeout handler for Alamofire request?

In my project I use Alamofire this way:

init() {
    let configuration = NSURLSessionCon         


        
相关标签:
9条回答
  • 2020-12-01 05:34

    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
                    }
                }
            })
        }
    
    }
    
    0 讨论(0)
  • 2020-12-01 05:48

    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

    0 讨论(0)
  • 2020-12-01 05:49

    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!")
                    }
                }
            }
    
    0 讨论(0)
  • 2020-12-01 05:49

    Swift 3, Alamofire 4.5.0

    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
        ...
    }
    
    0 讨论(0)
  • 2020-12-01 05:53

    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(let urlError as URLError) where urlError.code == .timedOut:
                print("Request timeout!")
            default:
                print("Other error!")
            }
        }
    }
    
    0 讨论(0)
  • 2020-12-01 05:56

    Make extension of SessionManager and write a public static variable like this, "requestTimeOutInterval" this is a public variable. it has time.

    extension SessionManager {
        public static let custom: SessionManager = {
            let configuration = URLSessionConfiguration.default
            configuration.timeoutIntervalForRequest = requestTimeOutInterval
            configuration.httpAdditionalHeaders = SessionManager.defaultHTTPHeaders
    
            return SessionManager(configuration: configuration)
        }()
    }
    
    0 讨论(0)
提交回复
热议问题