首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用带有注入属性的Decodable

使用带有注入属性的Decodable
EN

Stack Overflow用户
提问于 2021-03-24 21:50:08
回答 1查看 41关注 0票数 1

有没有办法使用带有注入属性的Decodable

代码语言:javascript
复制
final class Score: Decodable {
    let value: Int?
    let uniqueId: String

    convenience init(from decoder: Decoder/*, uniqueId: String*/) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        try container.decodeIfPresent(Int.self, forKey: .value).flatMap { value = $0 }
        // self.uniqueId = uniqueId
        [... other properties parsing ...]
    }
}

示例调用:

代码语言:javascript
复制
final class Exam {
    let identifier: Int
    let scores: [Score]
    
    convenience init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        identifier = try container.decode(Int.self, forKey: .identifier)
        scores = try container.decode([Score].self, forKey: .scores)
        // I need to pass Exam's identifier to `score` on init, because it will generate Score's `uniqueId `
        [... other properties parsing ...]
    }
}

这将以缺少uniqueId的错误结束,我需要在初始化之后拥有它,但它不在JSON中。因为它是标识符,所以将它设为可选并设置在外部不是处理它的正确方法。

我很乐意按照上面所说的方式注入它,但是该怎么做呢?

EN

回答 1

Stack Overflow用户

发布于 2021-03-25 19:32:35

没有办法扩展初始化器,因为它是间接调用的,并且没有提供API来扩展它。因此,有几种方法可以绕过它:

  1. BEST:如果对响应和模型分别使用possible.
  2. Create,则将值注入到解码器的userInfo中。下面的例子。
  3. 使用普通的JSONSerialization代替Decodable.
  4. As @JoakimDanielson建议,在默认初始化器中创建随机标识符。问题是它是不可重现的,所以如果您要将它保存到数据库中,您将始终覆盖数据,因为每次解析的ID都不同。

方法2的示例:

代码语言:javascript
复制
final class ScoreResponse: Decodable {
    let value: Int?

    convenience init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        try container.decodeIfPresent(Int.self, forKey: .value).flatMap { value = $0 }
        [... other properties parsing ...]
    }
}

final class Score {
    let value: Int?
    let uniqueId: String

    convenience init(from response: ScoreResponse, uniqueId: String) {
        self.value = response.value // etc with other properties
        self.uniqueId = uniqueId
    }
}

final class Exam: Decodable {
    let identifier: String
    let scores: [Score] = []
    
    convenience init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        identifier = try container.decode(String.self, forKey: .identifier)
        try container.decodeIfPresent([ScoreResponse].self, forKey: .scores).forEach {
        scores.append({ Score(from: $0, uniqueId: identifier) })
    }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66782493

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档