ios - 没有“decodeIfPresent”候选产生预期的上下文结果类型“[ModelMemberSubCategory]!”
问题描述
我有两个使用Codable
. 一个是ModelMemberCategory
& 另一个ModelMemberSubCategory
是 的子级ModelMemberCategory
。这是代码片段:
模型成员类别
struct ModelMemberCategory: Encodable {
var catId : Int!
var catName : String!
var fields : [ModelMemberSubCategory]!
//For Codable
enum CodingKeys: String, CodingKey {
case catId = "cat_id"
case catName = "cat_name"
case fields = "fields"
}
init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
catId = try values.decodeIfPresent(Int.self, forKey: .catId)
catName = try values.decodeIfPresent(String.self, forKey: .catName)
fields = try values.decodeIfPresent([ModelMemberSubCategory].self, forKey: .fields) // This line throws error on Xcode 9.4.1 but not on Xcode 9.2
}
}
模型成员子类别
struct ModelMemberSubCategory: Encodable{
var fieldCategory : String!
var fieldCode : String!
var fieldDatatype : String!
var fieldId : Int!
var fieldName : String!
var fieldType : String!
var fieldValue : String!
var fieldValuetype : String!
var fieldVisible : String!
//Codable
enum CodingKeys: String, CodingKey {
case fieldCategory = "field_category"
case fieldCode = "field_code"
case fieldDatatype = "field_datatype"
case fieldId = "field_id"
case fieldName = "field_name"
case fieldValue = "field_value"
case fieldValuetype = "field_valuetype"
case fieldVisible = "field_visible"
}
init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
fieldCategory = try values.decodeIfPresent(String.self, forKey: .fieldCategory)
fieldCode = try values.decodeIfPresent(String.self, forKey: .fieldCode)
fieldDatatype = try values.decodeIfPresent(String.self, forKey: .fieldDatatype)
fieldId = try values.decodeIfPresent(Int.self, forKey: .fieldId)
fieldName = try values.decodeIfPresent(String.self, forKey: .fieldName)
fieldValue = try values.decodeIfPresent(String.self, forKey: .fieldValue)
fieldValuetype = try values.decodeIfPresent(String.self, forKey: .fieldValuetype)
fieldVisible = try values.decodeIfPresent(String.self, forKey: .fieldVisible)
}
}
现在的问题是它在 Xcode 9.2 中的构建,而不是在 Xcode 9.4.1 中。当我尝试使用 9.4.1 构建时,我收到如下错误:
没有“decodeIfPresent”候选产生预期的上下文结果类型“[ModelMemberSubCategory]!”
在
fields = try values.decodeIfPresent([ModelMemberSubCategory].self, forKey: .fields)
在ModelMemberCategory
我不知道 Apple 在 Xcode 9.4.1 版本中发生了什么变化,但谁能帮我克服这个错误?
解决方案
你需要Decodable
而不是Encodable
. Decodable
需要将外部实体表示为您的类型
更改Encodable
为Decodable
修复错误。
代码在 XCode 9.2 中构建,因为在 Swift 4.0(<4.1) 中,编译器不会检查您的结构是否符合 Decodable。通过使用条件一致性,这在 Swift 4.1(XCode 9.3+)中得到了修复。
你可以在这里阅读更多关于它的信息。
在旁注中, in ModelMemberSubCategory
,fieldType
是缺失的。我希望它是故意的。
此外,decodeIfPresent
返回Optional
值,但您的所有实例变量都是非可选的。如果您认为某些变量可以为 nil,则应将它们设为 Optional,以便您可以更好地处理代码中的 nil 值。
推荐阅读
- javascript - Firefox 中 HTML 横幅上的可点击(Taparea)打开 Outlook 以及一个新选项卡
- c# - Asp.Net Core 中的 EF Core 异步可扩展性
- python - Pandas:如何创建一个包含月内每个工作日数的新列?
- oracle - 为什么这个检查约束在检查长度时不起作用?
- c# - 在c#中检测按键
- c++ - 如何在 Code::Blocks IDE 中打开文件夹?
- java - 试图制作一个创建2个移动矩形的java程序
- reactjs - 如何在单击另一个组件的按钮时更改组件的状态?
- md5 - MD5 加密选定的 GDrive 文件
- ruby-on-rails - Rails 动态 where 子句