如何使用 JSONDecoder 解码自定义 JSON 值

Posted

技术标签:

【中文标题】如何使用 JSONDecoder 解码自定义 JSON 值【英文标题】:How to decode custom JSON values using JSONDecoder 【发布时间】:2018-01-30 14:42:08 【问题描述】:

后端返回位置的自定义 JSON 值。如示例所示:


    "location": (54.000000, 21.000000)

为了解析 JSON,我使用以下代码:

let json = """

    "location": (54.000000, 21.000000)

"""    
struct Location: Codable 
    var latitude: Double
    var longitude: Double

let dataJson = json.data(using: .utf8)!
let location = try? JSONDecoder().decode(Location.self, from: dataJson)

当我尝试使用 JSONDecoder 创建 Location 对象时,它给了我一个错误:给定的数据不是有效的 JSON。

dataCorrupted(Swift.DecodingError.Context(codingPath: [], debugDescription: "The given data was not valid JSON.", underlyingError: Optional(Error Domain=NSCocoaErrorDomain Code=3840 "Invalid value around character 18." UserInfo=NSDebugDescription=Invalid value around character 18.)))

我知道它不是有效的 JSON。 覆盖哪些方法可以解析无效的 JSON 值?

【问题讨论】:

你不能改变你的后端来返回一个有效的 JSON 吗? @Balanced Backend 由 3rd 方管理,无法进行更改。 【参考方案1】:

如果第三方以一致的方式生成无效的 JSON,您可以使用正则表达式将其修复为有效的 JSON。 这不是万无一失的。如果 JSON 的格式不同,它可能会失败。最好的做法是要求第三方更正他们的后端。

您可以使用正则表达式将圆括号替换为方括号:

var json = """

"location": (54.000000, 21.000000)

"""

let regex = try! NSRegularExpression(pattern: "\\\"location\\\":\\s*\\((.+?)\\)", options: [])
let fullRange = NSRange(..<json.endIndex, in: json)

json = regex.stringByReplacingMatches(in: json, options: [], range: fullRange, withTemplate: "\"location\": [$1]")

您还需要将自定义解码器添加到您的 Location 结构,因为它现在被编码为数组:

struct Location: Decodable 
    var latitude: Double
    var longitude: Double

    init(from decoder: Decoder) throws 
        var container = try decoder.unkeyedContainer()
        latitude = try container.decode(Double.self)
        longitude = try container.decode(Double.self)
    

解码示例:

struct Response: Decodable 
    var location: Location

let dataJson = json.data(using: .utf8)!
let location = try JSONDecoder().decode(Response.self, from: dataJson)

【讨论】:

以上是关于如何使用 JSONDecoder 解码自定义 JSON 值的主要内容,如果未能解决你的问题,请参考以下文章

如何在 swift 4.1 和 xcode 9.3 中使用 JSONDecoder 解码嵌套的 JSON 数组和对象?

iOS - JSONEncoder和JSONDecoder介绍

JSONDecoder和JSONEncoder类是线程安全的吗?

如何在 swift 中使用 JSONDecoder 输入调整?

如何以这种日期格式使用 JSONDecoder / Codable?

使用 JSONDecoder Swift 解码具有整数值的字符串键 [关闭]