首页 > 解决方案 > JSON“字符 0 周围的值无效”,尽管 url 工作正常且 JSON 有效

问题描述

我有这个似乎随机弹出的 json 错误。

我从域加载 json 并将其解析为字典。如果错误没有发生,它就完美无缺。这是代码:

func retrieveCoinPairData() {

    guard !checkIfBaseAndTargetAreEqual() else { return }

    if let base = self.currentBase, let target = self.currentTarget {
        if let url = URL(string: "https://api.cryptonator.com/api/full/\(base.code)-\(target.code)") {

            URLSession.shared.dataTask(with: url, completionHandler: { (data, response, error) in

                if let error = error {
                    print(error.localizedDescription)
                }
                if let response = response {
                    print("reponse /api/full", response)
                }
                do {
                    if let data = data {
                        let jsonData = try JSONSerialization.jsonObject(with: data, options: .allowFragments) as! [String: Any]
                        self.createCoinPairData(with: jsonData)
                    } else {
                        self.delegate?.updateInfoLabelContent(content: .noInternetConnection)
                    }
                } catch {
                    self.delegate?.updateInfoLabelContent(content: .error)
                    print("catch error", error, data?.description as Any)
                    self.retrieveCoinPairData()
                }
            }).resume()
        } else {
            self.delegate?.updateInfoLabelContent(content: .error)
        }
    }
}

服务器响应如下,抛出 403 错误:

reponse /api/full <NSHTTPURLResponse: 0x608000232400> { 
URL: https://api.cryptonator.com/api/full/BTC-ETH } { 
status code: 403, headers {
    Connection = "keep-alive";
    "Content-Encoding" = gzip;
    "Content-Type" = "text/html";
    Date = "Tue, 05 Jun 2018 04:23:37 GMT";
    "Keep-Alive" = "timeout=15";
    Server = nginx;
    "Transfer-Encoding" = Identit

并且 URLSession 捕获错误如下:

catch error Error Domain=NSCocoaErrorDomain Code=3840 
"Invalid value around character 0." 
UserInfo={NSDebugDescription=Invalid value around character 0.}
Optional("162 bytes")

错误发生try JSONSerialization.jsonObject(with: data, options: .allowFragments) as! [String: Any]在行中。

现在,无论何时发生此错误(并且完全是随机的),当我在浏览器中检查 url 时,它都可以正常工作。

我用 jsonlint.com 检查了 json,它是有效的,没有顶级对象使 json 需要碎片,尽管该选项似乎减少了过去的错误。

我知道代码 403 错误告诉我网站阻止访问,代码 3840 错误告诉我没有要解析的内容。我仍然想知道错误发生的位置和原因。

这是本示例中使用的站点:https ://api.cryptonator.com/api/full/btc-eth

标签: jsonswiftmacosapiurlsession

解决方案


更改您的代码行以执行此操作:

if let error = error {
    print(error.localizedDescription)
    return
 }
 if let httpResponse = response as HTTPURLResponse {
    if httpResponse.statusCode == 200 {
         // do your json deserialization after you verify you 
         // got a 200 / OK from the server
         do {
            if let data = data {
                let jsonData = try JSONSerialization.jsonObject(with: data, options: .allowFragments) as! [String: Any]
                self.createCoinPairData(with: jsonData)
            } else {
                self.delegate?.updateInfoLabelContent(content: .noInternetConnection)
            }
        } catch {
            self.delegate?.updateInfoLabelContent(content: .error)
            print("catch error", error, data?.description as Any)
            self.retrieveCoinPairData()
        }
    } else {
        print("reponse /api/full", response)
    }
 }

你看到的是,如果你知道服务器向你发送了 200/OK 响应,你应该只尝试 JSON 反序列化。


推荐阅读