48 votes

Gérer le délai d'attente avec Alamofire

Est-il possible d'ajouter un gestionnaire de délai pour les demandes Alamofire ?

Dans mon projet, j'utilise Alamofire de cette façon :

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

EDITAR:

message d'échec de la demande

Error Domain=NSURLErrorDomain Code=-1001 "La demande a expiré". UserInfo={NSUnderlyingError=0x7fc10b937320 {Error Domain=kCFErrorDomainCFNetwork Code=-1001 "(null)" UserInfo={_kCFStreamErrorCodeKey=-2102, _kCFStreamErrorDomainKey=4}, NSErrorFailingURLStringKey=url, NSErrorFailingURLKey=url, _kCFStreamErrorDomainKey=4, _kCFStreamErrorCodeKey=-2102, NSLocalizedDescription=La demande a expiré. }

0 votes

Le délai d'attente ne déclenche-t-il pas également la fonction .Failure ? Je ne l'ai jamais testé avec Alamofire, mais la plupart des autres systèmes que j'utilise se replient sur l'erreur/la défaillance comme cela. Qu'avez-vous testé ?

0 votes

Allendar, vous avez raison, c'est ma faute si je ne l'ai pas mentionné. J'ai modifié ma question.

2 votes

L'objet réponse contiendra le statut HTTP. S'il s'agit d'un état 408 (408 Request Timeout), vous pouvez le vérifier à l'intérieur de la balise .Failure et le traiter de manière appropriée. Il existe probablement même des macros pour les états http, ce qui vous permet de vérifier simplement quelque chose comme HTTP_STATUS_408 comme un entier de remplacement.

99voto

kamwysoc Points 3917

Vous pouvez comparer error._code et si elle est égale à -1001 qui est NSURLErrorTimedOut alors vous savez que c'était un temps mort.

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

3 votes

C'est vrai, mais il n'est pas recommandé de le faire, car si vous travaillez en équipe, ces vérifications bizarres sur les codes exacts "sous l'eau" rendront le code très illisible. Néanmoins, c'est une réponse correcte, donc +1.

1 votes

Je suis tout à fait d'accord avec vous, j'ai fait quelques mises à jour pour rendre cet extrait plus lisible pour les humains :)

1 votes

J'ai fait quelques recherches et nous pouvons utiliser NSURLErrorTimedOut de NSURLError classe.

21voto

Anil Kukadeja Points 771

Swift 3

La réponse acceptée n'a pas fonctionné pour moi.

Après de nombreuses recherches, j'ai procédé comme suit :

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

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

13voto

ivoroto Points 149

Swift 3, Alamofire 4.5.0

Je voulais mettre le même délai d'attente pour chaque appel HTTP dans mon projet.

L'idée principale est de déclarer le Gestionnaire de session Alamofire comme une variable globale . Ensuite, pour créer un URLSessionConfiguration définit son délai d'attente en secondes et l'assigne au gestionnaire.

Chaque appel du projet peut utiliser cette configuration gestionnaire de session .

Dans mon cas, le global Gestionnaire de session Alamofire a été définie dans AppDelegate (de manière globale) et sa configuration était gérée dans son didFinishLaunchingWithOptions méthode

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

A partir de maintenant, le Demande d'Alamofire peut être appelée depuis n'importe quelle partie de l'application en utilisant la fonction afManager .

Par exemple :

AFManager.request("yourURL", method: .post, parameters: parameters, encoding: JSONEncoding.default).validate().responseJSON { response in
    ...
}

1 votes

Pouvez-vous fournir le code de la dernière version d'alamofire ? TKs

1 votes

A sauvé ma vie (Y)

5voto

Gurjit Singh Points 595

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

2voto

ventuz Points 386

Swift 3.x

La réponse acceptée n'a pas fonctionné pour moi aussi.

Ce travail pour moi !

let url = URL(string: "yourStringUrl")!
var urlRequest = URLRequest(url: url)
urlRequest.timeoutInterval = 5 // or what you want

Et après :

Alamofire.request(urlRequest).response(completionHandler: { (response) in
    /// code here
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X