web-dev-qa-db-fra.com

Alamofire responseSerializationFailed (Alamofire.AFError.ResponseSerializationFailureReason.inputDataNilOrZeroLength)

J'avais un code de travail qui obtenait des résultats d'une base de données MySQL sur un serveur Web distant. Cela ne fonctionne plus et je continue à recevoir le message responseSerializationFailed(Alamofire.AFError.ResponseSerializationFailureReason.inputDataNilOrZeroLength). Voici du code ...

    Alamofire.request(ADS_URL, method: .get).validate().responseJSON { response in
        print("Request: \(String(describing: response.request))")   // original url request
        print("Response: \(String(describing: response.response))") // http url response
        print("Result: \(response.result)")                         // response serialization result

        switch response.result {
        case .success(let value):
            let json = JSON(value)
            print ("JSON: \(json)")

            if let data = response.data, let utf8Text = String(data: data, encoding: .utf8) {
                print("Data: \(utf8Text)") // original server data as UTF8 string
            }

        case .failure(let error):
            print("Error while querying database: \(String(describing: error))")
            return
        }
    }

J'utilise aussi SwiftyJSON. Voici les résultats du code ...

Request: Optional(http://doyouado.com/adscan/get_ads)

Response: Optional(<NSHTTPURLResponse: 0x17502f3a0> { URL: http://doyouado.com/adscan/get_ads } { status code: 200, headers {
    Connection = "keep-alive";
    "Content-Length" = 0;
    "Content-Type" = "text/html; charset=UTF-8";
    Date = "Mon, 18 Sep 2017 16:04:37 GMT";
    Server = "nginx/1.12.1";
    "Set-Cookie" = "ado_session=a%3A5%3A%7Bs%3A10%3A%22session_id%22%3Bs%3A32%3A%225019d90891c70c81df8ebc2fe754a68f%22%3Bs%3A10%3A%22ip_address%22%3Bs%3A15%3A%22109.150.214.128%22%3Bs%3A10%3A%22user_agent%22%3Bs%3A86%3A%22ADoBroadcaster%2F1.0+%28com.GaryFrank.ADoBroadcaster%3B+build%3A1%3B+iOS+10.3.3%29+Alamofire%2F4.5.0%22%3Bs%3A13%3A%22last_activity%22%3Bi%3A1505750677%3Bs%3A9%3A%22user_data%22%3Bs%3A0%3A%22%22%3B%7D3130ef6f5541e6f944da5a5a1292350bf203fa1b; expires=Mon, 18-Sep-2017 18:04:37 GMT; Max-Age=7200; path=/";
} })

Result: FAILURE  

Error: responseSerializationFailed(Alamofire.AFError.ResponseSerializationFailureReason.inputDataNilOrZeroLength)

J'ai essayé d'utiliser .response et .responseString, mais je ne reçois aucune information. Je suis complètement stupéfait. Tout fonctionnait bien. J'espère qu'il y a quelqu'un qui peut faire la lumière sur cela?

5
gfgruvin

Ce qui a fonctionné pour moi a été de changer l'encodage de JSONEncoding.default à URLEncoding.default!

9
Will Said

Il suffit simplement de changer .responseJSON en .responseData.

Et après ces données d'analyse:

let jsonDecoder = JSONDecoder() 
let parsedData = try jsonDecoder.decode(T.self, from: data)

et pas d'erreur:

(Alamofire.AFError.ResponseSerializationFailureReason.inputDataNilOrZeroLength)
6
Igor Kruglik

Lorsque le serveur ne renvoie aucune réponse, Alamofire affiche ce message dans le bloc .failure si vous imprimez le message d'erreur. Techniquement, ce n'est pas une erreur. Alamofire n'a pas affiché ce message dans ses versions précédentes, mais depuis l'une des dernières mises à jour, il a commencé à l'afficher.

Comme je l'ai dit, ce n'est pas vraiment une erreur, mais pour moi, c'est un bug dans Alamorfire. Et il est très ennuyeux et trompeur de continuer à voir cela dans votre journal quand il n'y a pas d'erreur de votre côté client ou serveur.

Voici comment je l'ai fait taire:

if (response.data?.count)! > 0 {print(error)}

Et je le fais quand il n'y a pas de réponse du serveur, ce qui est le comportement attendu puisque le serveur n'est pas supposé envoyer de réponse dans certains cas.

Alamofire.request(MY_URL, method: .get, parameters: ["blabla": blablabla])
        .validate(statusCode: 200..<300)
        .responseJSON {
            response in
            switch response.result {
            case .success(let value):
                self.processResponse(value)
            case .failure(let error):
                if (response.data?.count)! > 0 {print(error)}
            }
    }

Le message d'erreur ne s'affiche donc pas lorsque rien n'est renvoyé par le serveur. À mon avis, cela devrait être le comportement par défaut.

0
zeeshan

Généralement, cette erreur survient lorsque votre API est de type "GET" et que vous transmettez le type "POST".

Le même problème que j'ai rencontré et ma solution est je remplace .post à .get et ensuite cette erreur supprimée. 

Pour AFNetworking 3.0: - Allez dans chemin donné,

pods> Pods> AFNetworking> Sérialisation> AFURLResponseSerialization.m

puis remplacez la ligne n ° 228 (self.acceptableContentTypes = [NSSet setWithObjects:@"application/json", @"text/json", @"text/javascript", nil];)

avec

self.acceptableContentTypes = [NSSet setWithObjects:@"application/json", @"text/json", @"text/javascript", @"text/html", nil];

En raison de votre réponse sous la forme de text/html mais que cela n’est pas mentionné dans AFNetworking, nous l’ajoutons manuellement.

Remarque: - Je débogue ce problème pour Alamofire.