swift - 如何使用 `Codable` 协议(protocol)解码部分双序列化的 json 字符串?

标签 swift swift4 codable

如何使用 Codable 协议(protocol)解码部分双序列化的 json 字符串?

    class Person : Codable {
        var name : String?
        var hobby : String?
    }
    class Family : Codable {
        var person: String?
        var person_: Person?
    }
    class PerfectFamily : Codable {
        var person: Person?
    }

    let jsonString = "{\"person\":\"{\\\"name\\\":\\\"Mike\\\",\\\"hobby\\\":\\\"fishing\\\"}\"}"
    do {
        // I could do this.
        let family = try JSONDecoder().decode(Family.self, from: Data(jsonString.utf8))
        family.person_ = try JSONDecoder().decode(Person.self, from: Data(family.person!.utf8))
        print(family)

        // However I want to write more simply like this. Do you have some idea?
        let perfectFamily = try JSONDecoder().decode(PerfectFamily.self, from: Data(jsonString.utf8)) // error
        print(perfectFamily)

    } catch {
        print(error)
    }

最佳答案

如果您无法修复双重编码的 json,您可以为 PerfectFamily 类提供您自己的自定义解码器方法,但我建议使用结构:


struct Person: Codable {
    let name: String
    let hobby: String
}

struct PerfectFamily: Codable {
    let person: Person
    init(from decoder: Decoder) throws {
        let container = try decoder.singleValueContainer()
        let person = try container.decode([String: String].self)["person"] ?? ""
        self.person = try JSONDecoder().decode(Person.self, from: Data(person.utf8))
    }
}

let json = "{\"person\":\"{\\\"name\\\":\\\"Mike\\\",\\\"hobby\\\":\\\"fishing\\\"}\"}"

do {
    let person = try JSONDecoder().decode(PerfectFamily.self, from: Data(json.utf8)).person
    print(person)   // "Person(name: "Mike", hobby: "fishing")\n"
} catch {
    print(error)
}

关于swift - 如何使用 `Codable` 协议(protocol)解码部分双序列化的 json 字符串?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47917525/

相关文章:

ios - Swift 闭包从函数返回

ios - 更新子字符串(到 :) results in generic parameter could not be inferred

ios - 无法使用协议(protocol)包含采用Codable的协议(protocol)

swift - 如何使 NSAttributedString 可编码兼容?

ios - 如何从父 View 中关闭 SwiftUI NavigationView

ios - Swift - viewController 之间无限滚动

ios - UITableViewController swift 不同大小的高度与图像

ios - 使用 UITextField 中的信息填写 PDF 文档

ios - 如何使用一个 ContainerView 显示多个 ViewController

ios - 带有泛型的Swift Codable,可保存响应中的通用数据