导致 JSON 解码在 Swift 4 中失败的可选 URL

SN8*_*N81 7 json-deserialization swift swift4 ios11

我试图弄清楚为什么使用可选 URL 会导致我的 JSON 解码使用 Swift 4 失败。我已经倾注了 WWDC“Foundation 的新功能”视频、Apples Playground 示例以及互联网上的许多地方,但是还没有找到解决办法。

这是我创建的一个测试来显示问题。说这是我的json数据:

let json = """
{
    "kind" : "",
    "total" : 2,
    "image_url" : "https://www.myawesomeimageURL.com/awesomeImage.jpg"
}
""".data(using: .utf8)!
Run Code Online (Sandbox Code Playgroud)

这是我的结构:

    struct BusinessService: Decodable {
    let kind: String?
    let total: Int
    let image_url : URL?
}
Run Code Online (Sandbox Code Playgroud)

这是我序列化它的地方:

let myBusiness = try? JSONDecoder().decode(BusinessService.self, from: json)
print(myBusiness)
Run Code Online (Sandbox Code Playgroud)

现在,问题是如果我收到缺少 image_url 的 json 数据,则 json 解码失败并给我零。

我很困惑为什么“种类”可以是一个可选的字符串,并且在它没有值时不会导致 json 解码失败,但 image_url 不能是一个可选的 URL,而不会导致 json 失败。

我一直在努力解决这个问题两天了,但没有运气。有没有人知道为什么会失败?

我确实注意到了另一个难题,那就是 json 中的 image_url 实际上不必是有效的图像 URL。我可以输入任何字符串并且我的结构被序列化,所以我想我可能误解了它是如何工作的。我认为只有当 URL 可以转换为有效的 URL 并且没有发生时,它才会自动填充。

对此的任何见解将不胜感激。

zou*_*oul 10

这按预期对我有用。设置image_urlnull或完全省略它会导致BusinessService使用nilimage_url字段的值进行有效解码:

struct Example: Decodable {
    let url: URL?
}

// URL is present. This works, obviously.
try JSONDecoder().decode(Example.self, from: """
    { "url": "foo" }
    """.data(using: .utf8)!)

// URL is missing, indicated by null. Also works.
try JSONDecoder().decode(Example.self, from: """
    { "url": null }
    """.data(using: .utf8)!)

// URL is missing, not even the key is present. Also works.
try JSONDecoder().decode(Example.self, from: """
    {}
    """.data(using: .utf8)!) // works, too
Run Code Online (Sandbox Code Playgroud)

当我为该字段提供无效的 URL 值(例如空字符串)时,会出现唯一的问题。所以我想这是你的问题?

// This throws: "Invalid URL string."
try JSONDecoder().decode(Example.self, from: """
    { "url": "" }
    """.data(using: .utf8)!)
Run Code Online (Sandbox Code Playgroud)

您必须通过发送null或保留整行来为 URL 字段发送“无”值,而不是发送空字符串。

我很困惑为什么“种类”可以是一个可选的字符串,并且在它没有值时不会导致 json 解码失败,但 image_url 不能是一个可选的 URL,而不会导致 json 失败。

不同之处在于,""在 JSON 中是有效值String,但不是有效 URL。