【问题标题】:How to use Swift's JSONSerialization when JSON returns a single stringJSON返回单个字符串时如何使用Swift的JSONSerialization
【发布时间】:2019-12-08 14:45:32
【问题描述】:

所以这可能是一个非常基本的问题,但我很好奇您将如何使用 Swift 中的 JSONSerialization 处理解析作为单个字符串返回的 JSON 对象。所以我正在玩一个免费的哈利波特 API,并注意到其中一条路线返回一个字符串 (https://www.potterapi.com/v1/sortinghat),它给出的响应只是哈利波特中四个房子之一的一个字符串。

"Ravenclaw"

下面是我的尝试。

do {
    let json = try JSONSerialization.jsonObject(with: data, options: []) as? String
    print("json: \(json)")
} catch {
    print("Error: \(error.localizedDescription)")
}

我认为只需将类型转换为 String 就足够了,但我只是收到以下错误:“错误:无法读取数据,因为它的格式不正确。

我知道有更好的方法来解析 JSON,例如使用 Codable,但我只是想了解它是如何工作的,然后再继续解决这个问题。

【问题讨论】:

  • 它不是 JSON,所以你无法解析它。捕获数据并将其编码为 UTF。
  • @DanielStorm 这将包括引号和换行符,它们几乎肯定不是值的一部分。这是一个 JSON 字符串。需要对其进行解析以获得预期值。

标签: json swift nsjsonserialization


【解决方案1】:

JSONSerialization 是错误的工具。你想使用 JSONDecoder,它在 Swift 中更有用:

let json = Data("""
"Ravenclaw"
""".utf8)

let result = try JSONDecoder().decode(String.self, from: json)

请注意,这需要 iOS 13.1 或 macOS 10.15.1。否则,您将需要使用@vadian 的答案。

【讨论】:

  • 关于上述的一个问题,因为请求返回一个随机的房子,我无法对响应进行硬编码,那么我将如何处理呢?
  • 我的json 变量只是为了在操场上演示它。你只需要传递你的 data 变量。这不是硬编码的。
  • 哦,好的,非常感谢,只是想弄清楚所有这些,如果问题是显而易见的,那么抱歉
  • JSONDecoder 使用带有默认(无)选项的 JSONSerialization。此代码引发dataCorrupted 错误,debugDescription“给定的数据不是有效的 JSON。” 和基础错误描述 “JSON 文本没有以数组或对象和选项开头允许未设置的片段。”
  • @RobNapier 我知道发生了什么。 JSONEncoder 和 JSONDecoder 现在默认支持顶级“原始”类型(字符串、数字、布尔值)。它没有在 JSONDecoder 中实现,但显然在 iOS (13.1) 和 macOS (10.15.1) 上的 JSONSerialization 中实现。 1)。请参阅bugs.swift.org/browse/SR-6163 上的 cmets。我还在莫哈韦沙漠。
【解决方案2】:

要反序列化非集合类型,您必须设置 .allowFragments 选项

let jsonString = """
"Slytherin"
"""

do {
    if let json = try JSONSerialization.jsonObject(with: Data(jsonString.utf8), options: .allowFragments) as? String {
        print("json: ", json)
    }
} catch {
    print("Error: ", error)
}

JSONDecoder 不起作用,它使用 no 选项调用底层JSONSerialization

将字符串反序列化为字符串的意义是另一个问题,这个也是这样

if let json = String(data: data, encoding: .utf8) {
    print("json: \(json)")
}

编辑: JSONDecoder 确实适用于 iOS 13.1+ 和 macOS 10.15.1+

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-08-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多