【问题标题】:Swift 4 decode simple root level json valueSwift 4 解码简单的根级 json 值
【发布时间】: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 并没有使用它。

标签: swift swift4 codable


【解决方案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
}

【讨论】:

【解决方案2】:

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-11-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多