Установить тайм-аут в Аламофире

Я использую Alamofire 4.0.1 и хочу установить тайм-аут для моего запроса. Я попробовал решения, приведенные в этом вопросе:

В первом случае он выбрасывает NSURLErrorDomain (время ожидания установлено правильно):

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
                }
            }

Во втором случае тайм-аут не заменяется и все равно устанавливается как 60 секунд.

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

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

Я бегу в ios 10.1

Мой код: (это не работает)

    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
        }
    }

Решена тема Glamub Alamofire: время ожидания установки Alamofire 4.3.0 приводит к ошибке NSURLErrorDomain #1931

16 ответов

Решение

Пожалуйста, попробуйте это:-

    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
    }

Alamofire 5.1 включает новый способ изменения запроса с закрытием в инициализаторе:

AF.request(url) { $0.timeoutInterval = 60 }
    .validate()
    .response { _ in // handle response here }

У меня тоже такая же проблема, я думаю, что нашел решение. Попробуй объявить SessionManager?или в вашем случае alamofireManager в классе, вне функции

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
       }
     }
   }

}

Если вы используете один экземпляр Alamofire, вы можете создать ленивую переменную, подобную этой:

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

}()

Работает на Swift 4.2

Попробуй это:

    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)

Как сказал Мэтт, проблема в следующем

Разница здесь в том, что инициализированный менеджер не принадлежит и освобождается вскоре после того, как он выходит из области видимости. В результате все незавершенные задачи отменяются.

Решение этой проблемы было написано rainypixels

Импортная основа импорта Аламофире

class NetworkManager {

    var manager: Manager?

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

И моя собственная версия

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)
                }
            }
        }
    }
}

Можно также сделать менеджер для этого

import Alamofire

struct AlamofireAppManager {

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

}

Основано на ответе @kamal-thakur.

Свифт 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
}

На основе ответа Letaief Achraf, но для Swift 5.0 а также 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
}()

Используйте эту переменную внутри APIManager или что-то подобное.

В Swift 5. Это можно сделать.

AF.sessionConfiguration.timeoutIntervalForRequest = 60

Основываясь на последней версии 5.4.4, вы можете установить время ожидания следующим образом:

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

Вот документация.

Пример:

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

AF.request(url, method: .get, requestModifier: { $0.timeoutInterval = .infinity }).validate().responseData { response in
    // Do something with the response ...
}

После долгих попыток я сделал следующее:

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)")

        }
    }

Я надеюсь, что это помогает;)

Если вы не хотите создавать UrlRequest самостоятельно, вы все равно можете использовать Alamofire для его создания.

    // 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()

Это работает для меня:

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

Ничто из вышеперечисленного не помогло мне: я нахожусь на swift 4.2Alamofire 4.5

Мне удалось решить это так:

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

}
      //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
}()

У меня есть код для Swift 2.3 надеюсь, это поможет вам, попробуйте

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

    alamoFireManager = Alamofire.Manager(configuration: configuration)
Другие вопросы по тегам