json - 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
解决方案
更改您的代码行以执行此操作:
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 反序列化。
推荐阅读
- php - PHP / PHP Unit / Artisan / Laravel 在下一个可用端口上重新启动应用程序
- javascript - 在没有 ngModel 的情况下将输入中的数字格式化为用户类型 - angular2
- kubernetes - Kubernetes - pod 具有未绑定的即时 PersistentVolumeClaims
- javascript - Javascript + Razor for(var in list) for (var; var < list, var++)?
- python-3.x - mRNA形成蛋白质
- javascript - 在这个 React 应用程序示例中,bind(this) 到底在做什么?
- maven-3 - maven:使用 junit 4 执行集成测试,覆盖父 pom 中的设置
- java - 如何在协议 netConf 和 Nso cisco 中使用 camunda
- r - 如何更改每个数据点的图例?
- ios-simulator - 如何从命令行将 ios 模拟器旋转为横向