【问题标题】:Swift4: Error while decoding json from fileSwift4:从文件中解码 json 时出错
【发布时间】:2018-01-02 12:06:23
【问题描述】:

这是我的第一篇文章,所以我希望一切都像它应该的那样结构化。 我希望任何人都可以帮助我解决我的问题。

我在 Swift 中从下载的文件中解码 JSON 时遇到以下问题:

词汇表.json 文件包含以下内容:

[
 {
   "english": "one",
   "deutsch": "eins",
   "theme": "numbers"
 },
 {
   "english": "two",
   "deutsch": "zwei",
   "theme": "numbers"
 }
]

JSON in file

我的 swift 4 - 代码:

public struct Vocabulary: Codable{
    let english: String
    let deutsch: String
    let theme: String
}


func decodeData(){
    DataManager.getJSONFromURL("vokabeln") { (data, error) in

        guard let data = data else {
            return
        }
        let decoder = JSONDecoder()

        do {
            let vocabulary = try decoder.decode(Vocabulary.self, from: data)
            print(vocabulary)
        } catch let e {
            print("failed to convert data \(e)")

        }
    }
}

public final class DataManager {
    public static func getJSONFromURL(_ resource:String, completion:@escaping (_ data:Data?, _ error:Error?) -> Void) {
        DispatchQueue.global(qos: .background).async {
            let url = URL(string: "https://onedrive.live.com/xxxxx/vokabeln.json")
            let data = try! Data(contentsOf: url!, options: .uncached)
            completion(data, nil)
        }
    }
}

如果我从以下多字符串中解码 Json:

    public let vokabeln: String = """
[
{
    "english": "one",
    "deutsch": "eins",
    "theme": "numbers"
},
{
    "english": "two",
    "deutsch": "zwei",
    "theme": "numbers"
}
]
"""

它可以工作,但如果我尝试从文件中解码它,我会收到以下错误消息:

数据转换失败 dataCorrupted(Swift.DecodingError.Context(codingPath: [], debugDescription: "The given data was not valid JSON.", underlyingError: Optional(Error Domain=NSCocoaErrorDomain Code=3840 "JSON text没有开始带有数组或对象以及允许未设置片段的选项。" UserInfo={NSDebugDescription=JSON 文本未以数组或对象开头,并且允许未设置片段的选项。})))

提前谢谢你。

亲切的问候,

【问题讨论】:

  • 您的 JSON 是一个字典数组,因此根据您的 Vocabulary 类,它应该是一个词汇对象数组。
  • 将 URL 粘贴到浏览器中并检查 JSON 是否有效。错误消息说不是。并且从不使用 Data(contentsOf 从远程 URL 加载数据。
  • 好的,谢谢您的提示。我该如何加载它?

标签: ios json swift4


【解决方案1】:

改变这个

let vocabulary = try decoder.decode(Vocabulary.self, from: data)

到这里

let vocabulary = try decoder.decode([Vocabulary].self, from: data)

它会给出一个Vocabulary 的数组,就像[Vocabulary] 一样。

希望对你有帮助。

【讨论】:

  • 非常感谢
  • 乐于助人:)。如果对您有帮助,请接受答案。
【解决方案2】:

我遇到了一个非常相似的错误:

捕获:dataCorrupted(Swift.DecodingError.Context(codingPath: [], debugDescription: "给定的数据不是有效的 JSON。", 基础错误:可选(错误域=NSCocoaErrorDomain 代码=3840 “字符 64 周围的形状错误的物体。” UserInfo={NSDebugDescription=字符周围的对象格式错误 64.})))

但出于完全不同的原因:

我的本​​地 json 是这样创建的:

"""
{
    "name": "Durian",
    "rate": 600,
    "city": "Cali"
    "description": "A fruit with a distinctive scent."
}
"""

错误信息非常明显。我忘了在“Cali”后面加上,

如果我理解正确,要计算 64 个字符,您必须从“名称”所在行的开头开始计算。意思是每行前面有 4 个空字符。因此数字〜64。你不需要计算{ 行的空格:)

放置逗号解决了问题。

【讨论】:

  • 不要猜测 ?。这个Codable 错误会告诉您错误的确切内容和在哪里
  • 耐心老师。直到最近我才不得不深入了解Codable 1。它是否告诉您缺少逗号?它只是说它的格式不好 2. 从"nli",我数了 43 个字符。现在假设您有一个 2000 长字符的 json 并且遇到了这个问题。除非其他开发人员发布了一个易于理解的小问题,否则您不会知道 :) 3. 我最初所做的只是查看dataCorrupted(Swift.DecodingError.Context 并尝试理解...直到后来我发现我需要调查整个错误
  • 1.不,但您可以推断它 2. 空格字符很重要,关键字符是"description" 之前的字符 使用 2000 个字符,您可以使用适当的String API 提取子字符串
  • " 是 "description" 之前的字符。但是在错误中没有任何地方可以推断它在 "description" 之前还是我遗漏了什么?我也不明白你的意思意思是你可以使用适当的String API提取子字符串你能详细说明吗?我没有把这个作为我最好的答案。只是我搜索了这个错误......找到了这个帖子。它的答案是'不适用,所以我粘贴了我自己的答案。我传达了我的知识。作为 9k 用户,我相信其他新手(或偶尔经验丰富的开发人员)会从这个答案中受益。
  • JSON 是一种非常易于管理的格式。你只需要记住一些规则。例如,像文字 Swift 字典 JSON 键/值对是用逗号分隔的。有了这些基本知识,您就可以看到(推断)缺少的逗号。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多