子类化 swift 通用可解码类型

2024-03-01

EDIT: As 罗布·纳皮尔写道 https://stackoverflow.com/a/49540809/9565342,Xcode 9.2 中存在该问题。在 Xcode 9.3 中,该问题不再相关。

我的服务器 json 响应都打包在里面data object:

{ 
    "data": {...}
}

所以我有以下通用类型来解析 JSON:

class DataContainer<T: Decodable>: Decodable {

    let data: T

    init(data: T)
        self.data = data
    }
}

大多数时候它工作正常,但有一个响应我还需要解析included字段所以我创建了SpecificDataContainer子类:

class SpecificDataContainer: DataContainer<DataObject> {
    let included: [IncludedObject]

    init() {
        included = []
        super.init(data: DataObject(id: ""))
    }
}

上面的实现给了我编译器错误'required' initializer 'init(from:)' must be provided by subclass of 'DataContainer'.

我实施了init(from:) in the SpecificDataContainer但编译器仍然给我同样的错误。

看来我在这里错过了一些明显的东西。我究竟做错了什么?这是我的完整代码:

import Foundation

let jsonData = """
{
    "data": {
        "id": "some_id"
    },
    "included": [
        {
            "id": "some_id2"
        }
    ]
}
""".data(using:.utf8)!

struct DataObject: Decodable {
    let id: String
}

struct IncludedObject: Decodable {
    let id: String
}

class DataContainer<T: Decodable>: Decodable {
    let data: T

    init(data: T) {
        self.data = data
    }
}

class SpecificDataContainer: DataContainer<DataObject> {
    let included: [IncludedObject]

    init() {
        included = []
        super.init(data: DataObject(id: ""))
    }

    required init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        var includedArray = try container.nestedUnkeyedContainer(forKey: .included)

        var includedObjects:[IncludedObject] = []
        while !includedArray.isAtEnd {
            let includedObject = try includedArray.decode(IncludedObject.self)
            includedObjects.append(includedObject)
        }
        self.included = includedObjects

        try super.init(from: decoder)
    }

    private enum CodingKeys: String, CodingKey {
        case data = "data"
        case included = "included"
    }
}

let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .iso8601
if let obj = try? decoder.decode(SpecificDataContainer.self, from: jsonData) {
    print("object id \(obj.data.id)")
} else {
    print("Fail!")
}

由于某种原因 Xcode 无法识别自动生成的init(from:)在子类中Codable(正如罗伯所说,这可能是一个错误)。在 Xcode 9.3 发布之前,您还可以通过将初始化程序添加到基类来解决此问题:

class DataContainer<T: Decodable>: Decodable {    
    let data: T

    enum CodingKeys: String, CodingKey {
        case data
    }
    
    required init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        data = try container.decode(T.self, forKey: .data)
    }
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

子类化 swift 通用可解码类型 的相关文章

随机推荐

  • 在java中创建指定名称的临时文件

    我有一个 Byte 数组 我想将其内容放入临时文件中 我尝试这样做 try tempFile File createTempFile tmp null FileOutputStream fos new FileOutputStream te
  • 调试时从数据行获取所有列名/列值

    我正在创建一个数据行的模拟实例以进行测试 我尝试从数据库中复制的行包含 37 列 其中包含不同的变量 调试时是否有机会以干净的文本形式获取信息 以便简单地编辑我的模拟对象 我必须调整尼基尔的演员阵容 var colNames dr Tabl
  • 使用 C# 确定谁打开了文件

    使用 C 如何获取有关谁打开了文件的信息 用户名和机器名就足够了 以防万一 我有 Windows 工作站通过 Samba 访问 Linux 文件服务器上的文件 我在工作站上运行的程序中需要此信息 核心 NET 库没有任何方法可以做到这一点
  • 访问指针指向的整数数组时,“sizeof”对不完整类型“int[]”的无效应用

    我正在尝试学习 C 中的指针 并正在编写这个小整数数组指针练习 但遇到了无效的应用程序sizeof不完整类型int 问题 请告诉我哪里出了问题以及如何解决 谢谢 include
  • 在非标准位置安装带有库的 sf 包

    所需的库位于非标准位置 我可以通过以下命令安装 rgdal install packages rgdal type source configure args c with gdal config home programs anacond
  • 您会使用 实现轻量级 XML 解析器吗?

    如果您必须实现一个轻量级 XML 解析器 您会选择使用正则表达式吗 在我的例子中 XML 解析是最简单的 只有标签和文本内容 没有命名空间 没有属性 没有模式支持 当然是在一开始 但也许 我认为学习新的 C 0x 库对我来说是一个很好的练习
  • 将日期中的 NA 替换为另一个日期

    Data DB1 lt data frame orderItemID 1 10 orderDate c 2013 01 21 2013 03 31 2013 04 12 2013 06 01 2014 01 01 2014 02 19 20
  • WAMP服务器呈绿色但只得到404

    好吧 女士们先生们 我有一个很令人困惑的问题 我在工作中的 WIN7 机器上安装了 WAMP 服务器 一切都工作正常 有几个星期没有使用它 因为我被其他事情吸引了 有一天 我尝试启动它 图标是绿色的 我认为我们做得很好 然后我尝试打开 lo
  • 邮件脚本 - 解析错误:语法错误,意外的“=”[关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我正在尝试从包含下拉列表的 html 表单设置一个简单的邮件脚本 但在声明所选变量的行上我收到一条错误消息 解析错误 语法错误 意外的 我
  • 如何手动解密 EncryptedAssertion

    我想解密 EncryptedAssertion 我尝试使用 OpenSaml Decrypter 但它对我不起作用 我无法解密 EncryptedData 我已经问过这个问题了 EncryptedAssertion 解密失败 https s
  • Selenium:遍历元素列表

    我正在使用 XPath CSS 和 Selenium 来定位网站上的元素 我想创建一种方法 在该方法中迭代定位器列表 XPath CSS 程序选择有效的一个 换句话说 它从定位器一开始 如果定位器存在 则返回 true 并存在循环 否则 它
  • winHTTP GET 请求 C++

    我就开门见山吧 这就是浏览器请求的样子 获取 index html HTTP 1 1 这就是 winHTTP 的作用 GET http site com index html http site com index htmlHTTP 1 1
  • Java用户类

    如何解析java用户类和JDBC用户类 问题是当我用完 put 时 sql 中有数据 例如 public User authenctication String eMail String password try con DriverMan
  • String 是关于 switch 的数字类型并且总是编译为 LookupSwitch 吗?

    以下代码返回是否给定String s等于任何其他硬编码字符串 该方法使用switch 这样做的声明 public class SwitchOnString public static boolean equalsAny String s s
  • 在 Laravel 中使用自动控制器路由是一个坏主意

    我从 CodeIgniter 转到 Laravel 那么 使用自动路由到所有控制器是一个坏主意吗 Route controller Controller detect 我应该使用它而不是在routes php 中创建路由吗 是的 这很糟糕
  • 应该如何使用 std::Optional?

    我正在阅读以下文档std experimental optional http en cppreference com w cpp utility optional我很清楚它的作用 但我不明白when我应该使用它或者我应该如何使用它 该网站
  • 如何在perl中将十六进制转换为字符字符串

    我需要将 xx 十六进制字符更改为字符 我正在尝试使用此代码 但它不起作用 usr bin perl w my cadena 40 61 62 print cadena n cadena s g print cad cadena n my
  • 使用 opencv 的 Android 文档扫描仪

    我正在尝试在我的应用程序中开发文档扫描仪 作为我想要实现的目标的一个示例 您可以看一下 Google 云端硬盘应用程序中内置的 Google 文档扫描仪 这允许 检测边缘 操纵透视 显示文档的自上而下视图 我一直在研究一些第三方 api 看
  • android:媒体记录器:启动失败:-38

    简介 如何检查录音是否已在其他应用程序的后台运行 详细信息 如果录音已在本机应用程序的后台运行 录音机 现在我已将录音作为我的应用程序中的功能之一 问题 当我尝试同时在我的应用程序中录制时 出现错误 E MediaRecorder star
  • 子类化 swift 通用可解码类型

    EDIT As 罗布 纳皮尔写道 https stackoverflow com a 49540809 9565342 Xcode 9 2 中存在该问题 在 Xcode 9 3 中 该问题不再相关 我的服务器 json 响应都打包在里面da