Swift4:从文件中解码 json 时出错

Posted

技术标签:

【中文标题】Swift4:从文件中解码 json 时出错【英文标题】:Swift4: Error while decoding json from file 【发布时间】: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 加载数据。 好的,谢谢您的提示。我该如何加载它? 【参考方案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 键/值对是用逗号分隔的。有了这些基本知识,您就可以看到(推断)缺少的逗号。

以上是关于Swift4:从文件中解码 json 时出错的主要内容,如果未能解决你的问题,请参考以下文章

仅在运行时知道类型时的 Swift 4 JSON 解码

Swift 4 JSON 解码根数组

Swift 4 可解码的 json 数组

Swift 4 - Json 解码器

Swift 4 - 解码期间字符串转换为大写

在 swift 4 中使用可编码的 JSON 时出错?