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

时间:2018-10-23 06:11:57

标签: ios swift model codable

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

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

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进行构建时,出现如下错误:

  

没有'decodeIfPresent'候选者产生预期的上下文结果   输入“ [ModelMemberSubCategory]!”

fields = try values.decodeIfPresent([ModelMemberSubCategory].self, forKey: .fields)ModelMemberCategory

我不知道Apple在Xcode 9.4.1版本中做了什么更改,但是有人可以帮助我克服此错误吗?

1 个答案:

答案 0 :(得分:0)

您需要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值。