如何在Swift 4中实现JSON数据的多态解码?

如何在Swift 4中实现JSON数据的多态解码?,第1张

概述我试图从API端点返回的数据中呈现视图.我的 JSON看起来(大致)像这样: { "sections": [ { "title": "Featured", "section_layout_type": "featured_panels", "section_items": [ { "item_type": "foo 我试图从API端点返回的数据中呈现视图.我的 JSON看起来(大致)像这样:

{  "sections": [    {      "Title": "Featured","section_layout_type": "featured_panels","section_items": [        {          "item_type": "foo","ID": 3,"Title": "Bisbee1","audio_url": "http://example.com/foo1.mp3","feature_image_url" : "http://example.com/feature1.jpg"        },{          "item_type": "bar","ID": 4,"Title": "Mortar8","vIDeo_url": "http://example.com/vIDeo.mp4","director" : "John Smith","feature_image_url" : "http://example.com/feature2.jpg"        }      ]    }      ]}

我有一个对象,表示如何在我的UI中布局视图.它看起来像这样:

public struct VIEwLayoutSection : Codable {    var Title: String = ""    var sectionLayoutType: String    var sectionItems: [VIEwLayoutSectionItemable] = []}

VIEwLayoutSectionItemable是一种协议,其中包括标题和要在布局中使用的图像的URL等.

但是,sectionItems数组实际上由不同类型组成.我想要做的是将每个section项实例化为它自己的类的一个实例.

如何为VIEwLayoutSection设置init(来自解码器:解码器)方法,让我迭代该JsON数组中的项并在每种情况下创建正确类的实例?

解决方法 我建议你明智地使用Codable.如果您只想从JsON解码类型而不对其进行编码,那么仅将其与Decodable相符就足够了.既然你已经发现你需要手动解码它(通过自定义的init实现(来自解码器:解码器)),那么问题就变成了:最不痛苦的方法是什么?

一,数据模型.请注意,VIEwLayoutSectionItemable及其采用者不符合Decodable:

enum ItemType: String,Decodable {    case foo    case bar}protocol VIEwLayoutSectionItemable {    var ID: Int { get }    var itemType: ItemType { get }    var Title: String { get set }    var imageURL: URL { get set }}struct Foo: VIEwLayoutSectionItemable {    let ID: Int    let itemType: ItemType    var Title: String    var imageURL: URL    // Custom propertIEs of Foo    var audioURL: URL}struct bar: VIEwLayoutSectionItemable {    let ID: Int    let itemType: ItemType    var Title: String    var imageURL: URL    // Custom propertIEs of bar    var vIDeoURL: URL    var director: String}

接下来,我们将如何解码JsON:

struct Sections: Decodable {    var sections: [VIEwLayoutSection]}struct VIEwLayoutSection: Decodable {    var Title: String = ""    var sectionLayoutType: String    var sectionItems: [VIEwLayoutSectionItemable] = []    // This struct use snake_case to match the JsON so we don't have to provIDe a custom    // CodingKeys enum. And since it's private,outsIDe code will never see it    private struct GenericItem: Decodable {        let ID: Int        let item_type: ItemType        var Title: String        var feature_image_url: URL        // Custom propertIEs of all possible types. Note that they are all optionals        var audio_url: URL?        var vIDeo_url: URL?        var director: String?    }    private enum CodingKeys: String,CodingKey {        case Title        case sectionLayoutType = "section_layout_type"        case sectionItems = "section_items"    }    public init(from decoder: Decoder) throws {        let container     = try decoder.container(keyedBy: CodingKeys.self)        Title             = try container.decode(String.self,forKey: .Title)        sectionLayoutType = try container.decode(String.self,forKey: .sectionLayoutType)        sectionItems      = try container.decode([GenericItem].self,forKey: .sectionItems).map { item in        switch item.item_type {        case .foo:            // It's OK to force unwrap here because we already            // kNow what type the item object is            return Foo(ID: item.ID,itemType: item.item_type,Title: item.Title,imageURL: item.feature_image_url,audioURL: item.audio_url!)        case .bar:            return bar(ID: item.ID,vIDeoURL: item.vIDeo_url!,director: item.director!)        }    }}

用法:

let sections = try JsONDecoder().decode(Sections.self,from: Json).sections
总结

以上是内存溢出为你收集整理的如何在Swift 4中实现JSON数据的多态解码?全部内容,希望文章能够帮你解决如何在Swift 4中实现JSON数据的多态解码?所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1005736.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-22
下一篇 2022-05-22

发表评论

登录后才能评论

评论列表(0条)

保存