Swift 4可分解的多个容器 [英] Swift 4 Decodable multiple containers

查看:75
本文介绍了Swift 4可分解的多个容器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图了解如何将这个多容器JSON解析为一个对象。我已经尝试了这种方法(马克回答),但他解释了如何使用一级容器解决该问题。由于某些原因,我无法模仿多个容器的行为。

I'm trying to understand how could I parse this multiple container JSON to an object. I've tried this approach (Mark answer), but he explain how to solve it using one-level container. For some reason I can't mimic the behaviour for multiple containers.

 {
     "graphql": {
        "shortcode_media": {
          "id": "1657677004214306744",
          "shortcode": "BcBQHPchwe4"
        }
     }
  }







class Post: Decodable {


    enum CodingKeys: String, CodingKey {
        case graphql // The top level "user" key
        case shortcode_media
    }

    enum PostKeys: String, CodingKey {
        case id
    }

    required init(from decoder: Decoder) throws {

        let values = try decoder.container(keyedBy: CodingKeys.self)

        let post = try values.nestedContainer(keyedBy: PostKeys.self, forKey: .shortcode_media)

        self.id = try post.decode(String.self, forKey: .id)

    }

    var id: String

}

我得到:

Swift.DecodingError.Context(codingPath: [], debugDescription: "Cannot get KeyedDecodingContainer<PostKeys> -- no value found for key \"shortcode_media\"", underlyingError: nil))

非常感谢您的帮助!

推荐答案

阅读

任何开头 {都是一个分隔符。JSON的缩进还表示层次结构。

Any opening { is quasi a separator. The indentation of the JSON indicates also the hierarchy.

为清楚起见,我删除了所有编码键,并保留了变量名(应为 camelCased )。

For clarity I removed all coding keys and left the variable names – which should be camelCased – unchanged.

struct Root : Decodable {
    let graphql : Graph

    // to access the `Media` object declare a lazy instantiated property

    lazy var media : Media = {
        return graphql.shortcode_media
    }()
}

struct Graph : Decodable {
    let shortcode_media : Media
}

struct Media : Decodable {
    let id: String
    let shortcode : String
}



< hr>


let jsonString = """
{
    "graphql": {
        "shortcode_media": {
            "id": "1657677004214306744",
            "shortcode": "BcBQHPchwe4"
        }
    }
}
"""







do {       
    let data = Data(jsonString.utf8) 
    var result = try decoder.decode(Root.self, from: data)
    print(result.media)
} catch {
    print("error: ", error)
}






使用 nestedContainer 编写自定义初始化程序比创建实际的层次结构要费更多的精力。


Writing a custom initializer with nestedContainer is more effort than creating the actual hierarchy.

请粘贴整个代码放在一个Playground中,然后签出。

Please paste the entire code in a Playground and check it out.

这篇关于Swift 4可分解的多个容器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆