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

No 'decodeIfPresent' candidates produce the expected contextual result type '[ModelMemberSubCategory]!'

我有两个使用 Codable 的自定义结构模型。一个是 ModelMemberCategory,另一个是 ModelMemberSubCategory,即 ModelMemberCategory 的 child。这是代码片段:

模型成员类别

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
    } 
}

ModelMemberSubCategory

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

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