无法读取数据,因为格式不正确? [英] The Data Couldn't Be Read Because It Isn't in The Correct Format?

查看:344
本文介绍了无法读取数据,因为格式不正确?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我很确定我的模型基于我的数据是正确的,我无法弄清楚为什么会出现格式错误?

I'm pretty sure my model is correct based on my data, I cannot figure out why I am getting the format error?

JSON:

{
   "1596193200":{
      "clientref":1,
      "type":"breakfast"
   },
   "1596200400":{
      "clientref":0,
      "type":"lunch"
   },
   "1596218400":{
      "clientref":2,
      "type":"dinner"
   }
}

型号:

struct Call: Decodable {
    let clientref: Int?
    let type: String?
}

用用于从URL解码json数据的代码编辑更新的问题:

edit updated question with the code for decoding the json data from the URL:

class CallService {
    
    static let shared = CallService()
    let CALLS_URL = "url.com/Calls.json"

    func fetchCalls(completion: @escaping ([Call]) -> ()) {

        guard let url = URL(string: CALLS_URL) else { return }

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

            // handle error
            if let error = error {
                print("Failed to fetch data with error: ", error.localizedDescription)
                return
            }

            guard let data = data else {return}

            do {
                let call = try JSONDecoder().decode([Call].self, from: data)
                completion(call)


            } catch let error {
                print("Failed to create JSON with error: ", error.localizedDescription)
            }
        }.resume()
    }
}

推荐答案

我强烈建议学习如何调试:它包括查找位置,获取哪些信息,从何处获取等等,最后进行修复它.

I strongly suggest to learn how to debug: it includes where to look, what info to get, where to get them, etc, and at the end, fix it.

这是一件好事,您可以打印错误,而大多数初学者则不用.

That's a good thing that you print the error, most beginner don't.

print("Failed to create JSON with error: ", error.localizedDescription)

=>

print("Failed to create JSON with error: ", error)

您会得到一个更好的主意.

You'll get a better idea.

第二,如果失败,则打印字符串化的数据.您应该拥有JSON,没错.但是我经常看到关于该问题的问题,但实际上答案根本不是JSON(API从未声明它将返回JSON),而作者却遇到了错误(自定义404等),并且确实得到了XML/HTML消息错误等.

Second, if it failed, print the data stringified. You're supposed to have JSON, that's right. But how often do I see question about that issue, when it fact, the answer wasn't JSON at all (the API never stated it will return JSON), the author were facing an error (custom 404, etc.) and did get a XML/HTML message error etc.

因此,当解析失败时,我建议这样做:

So, when the parsing fails, I suggest to do:

print("Failed with data: \(String(data: data, encoding: .utf8))")

检查输出是否为有效的JSON(很多在线验证器或执行此操作的应用程序).

Check that the output is a valid JSON (plenty of online validators or apps that do that).

现在:

我很确定根据我的数据我的模型是正确的

I'm pretty sure my model is correct based on my data,

是的,是的,不是.

首次亮相时使用Codable的小技巧(不使用嵌套的东西):相反.

Little tip with Codable when debuting (and not using nested stuff): Do the reverse.

如果还不是,请让您的结构可编码(我使用过Playgrounds)

Make your struct Codable if it's not the case yet (I used Playgrounds)

struct Call: Codable {
    let clientref: Int?
    let type: String?
}


do {
    let calls: [Call] = [Call(clientref: 1, type: "breakfast"),
                          Call(clientref: 0, type: "lunch"),
                          Call(clientref: 2, type: "dinner")]
    
    let encoder = JSONEncoder()
    encoder.outputFormatting = [.prettyPrinted]
    let jsonData = try encoder.encode(calls)
    let jsonStringified = String(data: jsonData, encoding: .utf8)
    if let string = jsonStringified {
        print(string)
    }
} catch {
    print("Got error: \(error)")
}

输出:

[
  {
    "clientref" : 1,
    "type" : "breakfast"
  },
  {
    "clientref" : 0,
    "type" : "lunch"
  },
  {
    "clientref" : 2,
    "type" : "dinner"
  }
]

它看起来不像.我只能使用数组将各种调用放入单个变量中,这就是您要进行解码的含义,因为您编写了[Call].self,因此您期望的是Call的数组.我们错过了"1596218400&"部分.等等,这可能是顶级词典吗?是的.您可以看到{}及其使用键"的事实,而不是一个接一个地列出...

It doesn't look like. I could only used an array to put various calls inside a single variable, and that's what you meant for decoding, because you wrote [Call].self, so you were expecting an array of Call. We are missing the "1596218400" parts. Wait, could it be a dictionary at top level? Yes. You can see the {} and the fact it uses "keys", not listing one after the others...

等等,但是既然我们打印了完整的错误,那么现在更有意义了吗?

Wait, but now that we printed the full error, does it make more sense now?

typeMismatch(Swift.Array<Any>, 
             Swift.DecodingError.Context(codingPath: [],         
                                         debugDescription: "Expected to decode Array<Any> but found a dictionary instead.", 
                                         underlyingError: nil))

修复:

let dictionary = try JSONDecoder().decode([String: Call].self, from: data)
completion(dictionary.values) //since I guess you only want the Call objects, not the keys with the numbers.

这篇关于无法读取数据,因为格式不正确?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆