ios - 没有 'decodeIfPresent' 候选产生预期的上下文结果类型 '[ModelMemberSubCategory]!'

标签 ios swift model codable

我有两个使用 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 构建时,我遇到了这样的错误:

No 'decodeIfPresent' candidates produce the expected contextual result type '[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 或不。 通过使用 Conditional conformance.,这在 Swift 4.1(XCode 9.3+)中得到修复
您可以阅读更多相关信息 here.

附带说明,在 ModelMemberSubCategory 中,缺少 fieldType。我希望它是故意的。
此外,decodeIfPresent 返回 Optional 值,但您的所有实例变量都是非可选值。如果您认为某些变量可以为 nil,则应将它们设为 Optional,以便您可以更好地处理代码中的 nil 值。

关于ios - 没有 'decodeIfPresent' 候选产生预期的上下文结果类型 '[ModelMemberSubCategory]!',我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52942223/

相关文章:

xcode - 在 Swift 中返回一个未包装的可选?

django - 过滤 Django 管理员选择框的模型结果

mysql - 如何在 mysql 上按 ID 分组并仅计算 5 的值?

django - 如何在 Django 模型中限制_choices_to self 字段 id

ios - Popover 并没有解雇自己

arrays - 使用 boolean 数组选择特定索引进行转换

c# - 自定义 UITableViewCell : First Row Has No Content

objective-c - func session(..) 在 WatchKit 中不会被调用

ios - 有没有办法在 SwiftUI 中实现 "unbind"变量/对象

ios - 自定义 UIImage 作为 UIBarButtonItem 显示像素化/模糊