Swift 4 解码简单的根级 json 值

Posted

技术标签:

【中文标题】Swift 4 解码简单的根级 json 值【英文标题】:Swift 4 decode simple root level json value 【发布时间】:2017-10-16 10:48:58 【问题描述】:

根据 JSON 标准RFC 7159,这是有效的 json:

22

如何使用 swift4 的可解码器将其解码为 Int?这不起作用

let twentyTwo = try? JSONDecoder().decode(Int.self, from: "22".data(using: .utf8)!)

【问题讨论】:

这不是一个有效的 json,一个 json 是由键值对组成的,它只是一个值。 这是有效的 JSON 片段,不是有效的 JSON。 如果您将try 包装在Do..Catch 中并处理错误,它会告诉您您的json 格式不正确。这不是一个有效的 JSON,你为什么要坚持这个? JSONSerialization 有一个 allowFragments 用于此目的的读取选项,但新的 JSONDecoder 没有这样的选项。 @Desdenova 我并不坚持,它根据 RFC 7159 标准是有效的,该标准肯定被广泛使用。如果你说的是真的,我想这意味着 swift 并没有使用它。 【参考方案1】:

它适用于良好的 ol' JSONSerialization.allowFragments 阅读选项。来自documentation:

allowFragments

指定解析器应该允许不是 NSArray 或 NSDictionary 实例的***对象。

例子:

let json = "22".data(using: .utf8)!

if let value = (try? JSONSerialization.jsonObject(with: json, options: .allowFragments)) as? Int 
    print(value) // 22

但是JSONDecoder没有这个选项,不接受*** 不是数组或字典的对象。可以看到在 source code decode() 方法调用 JSONSerialization.jsonObject() 没有任何选项:

open func decode<T : Decodable>(_ type: T.Type, from data: Data) throws -> T 
    let topLevel: Any
    do 
       topLevel = try JSONSerialization.jsonObject(with: data)
     catch 
        throw DecodingError.dataCorrupted(DecodingError.Context(codingPath: [], debugDescription: "The given data was not valid JSON.", underlyingError: error))
    

    // ...

    return value

【讨论】:

您可以尝试向 Apple 提交错误报告。 我忘了写这个但是我在这里提交了一个问题bugs.swift.org/browse/SR-6163【参考方案2】:

ios 13.1+ 和 macOS 10.15.1+ 中,JSONDecoder 可以在根级别处理 primitive 类型。

在 Martin 的答案下方的链接文章中查看最新的 cmets(2019 年 10 月)。

【讨论】:

以上是关于Swift 4 解码简单的根级 json 值的主要内容,如果未能解决你的问题,请参考以下文章

Swift 4 JSON Decodable 解码类型更改的最简单方法

Swift 4 可解码 - 附加变量

使用可选值 Swift 4 解码嵌套 JSON

Swift 4 Xcode 使用 JSON 解码的问题

Swift:用未知键解码 JSON? [复制]

如何从 JSON 对象 Swift 4 中检索值