Alamofire响应序列化失败(Alamofire.AFError.ResponseSerializationFailureReason.inputDataNilOrZeroLength)

25

我曾有一些代码,可以从远程Web服务器的MySQL数据库中获取结果。现在它不再工作了,我一直收到这条消息:responseSerializationFailed(Alamofire.AFError.ResponseSerializationFailureReason.inputDataNilOrZeroLength)。以下是一些代码...

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

我也在使用SwiftyJSON。这是代码的结果...

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)

我已经尝试使用.response.responseString,但是没有返回任何信息。我完全被卡住了。这些都曾经正常工作。希望有人能够解释一下?


你确定该URL指向一个有效的JSON吗? - Kyle Higginson
该URL是一个PHP脚本,它查询MySQL并将结果作为JSON返回。echo json_encode($ads); - gfgruvin
1
尝试使用responseString代替responseJSON,并打印出response.result.value,看看为什么无法序列化。你可能会得到HTML或其他内容。 - boidkan
使用responseString,返回一个空字符串到response.result.value。如果我在浏览器中输入URL,我可以看到JSON格式的数据。我检查了JSON,它是有效的。 - gfgruvin
@boidkan 谢谢,这对我很有用! - iAleksandr
7个回答

16

只需将 .responseJSON 更改为 .responseData

然后解析数据:

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

没有错误:

(Alamofire.AFError.ResponseSerializationFailureReason.inputDataNilOrZeroLength)

1
一开始为什么会发生这种情况,你有什么想法吗? - thibaut noah
2
@thibautnoah 因为空字符串不是有效的 JSON。 - IliaEremin

15

对我有用的是将编码从JSONEncoding.default更改为URLEncoding.default!


对我来说,情况恰好相反。我的是一个http-post请求,我将编码从URLEncoding.httpBody更改为JSONEncoding.default - Ahmet Gokdayi

11

从 Alamofire 4 升级到 5 导致我的问题。 默认情况下,Alamofire 5 返回错误 Alamofire.AFError.ResponseSerializationFailureReason.inputDataNilOrZeroLength 来表示状态码为 200 的空响应体。因此,将 200 添加到 emptyResponseCodes 列表中可以解决我的问题:

request.responseData(emptyResponseCodes: [200, 204, 205]) { ... } // the default is [204, 205]

1
这对我的PATCH请求也起作用了。谢谢naydin! - jrend

5
我成功的方法是将.responseData 替换为 .response。

0

虽然这个问题很旧了,但我想向其他人提供我最近发现的信息。

由于错误信息非常通用,没有什么帮助,所以请检查您使用的URL格式是否正确。我曾经遇到过这种情况,只有发现URL格式不正确后,才开始正常工作。


0

通常出现这个错误是因为您的API是“GET”类型,而您传递了“POST”类型。

我也遇到了同样的问题,我的解决方案是将.post替换为.get,然后这个错误就消失了。

对于AFNetworking 3.0:

前往以下路径:

pods > Pods > AFNetworking > Serialization > AFURLResponseSerialization.m

然后将第228行(self.acceptableContentTypes = [NSSet setWithObjects:@"application/json", @"text/json", @"text/javascript", nil];)替换为

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

由于您以 text/html 的形式响应,但在 AFNetworking 中没有提到,因此我们需要手动添加。

注意:我正在为 Alamofire 调试此问题。


抱歉,兄弟,我更新了我的答案到Afnetworking。如果这个问题出现在Afnetworking中,那么这就是正确的答案。 - Bijender Singh Shekhawat

0
当服务器没有响应时,如果您打印错误消息,则 Alamofire 在 .failure 块中显示此消息。从技术上讲,这不是一个错误。Alamofire 在早期版本中没有显示此消息,但自近期更新之一以来开始显示它。
正如我所说,这实际上不是一个错误,但对我来说,这是 Alamorfire 中的一个漏洞。当客户端或服务器端没有错误时,在日志中不断看到这个消息非常令人恼火和误导。
以下是我如何将其静音: if (response.data?.count)! > 0 {print(error)} 当服务器没有响应时我这样做,这是预期的行为,因为在某些情况下服务器不应发送响应。
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)}
            }
    }

所以当服务器没有返回任何内容时,错误信息不会显示。我认为这应该是默认行为。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接