快速创建具有默认值的非可选编码的最佳方法

问题描述 投票:2回答:3

我知道classstruct的基本概念,但是对于创建API来获取数据并告诉我正反两方面的模型而言,这更有效。

以前,我不为模型使用可选的。相反,我给它一些价值。即

class CompanyInfo : Codable {
    var NameEn : String = ""
    var CityEn : String = ""
    var Website : String = ""
    var Email : String = ""
    var Phone : String = ""
    var Fax : String = ""
}

但是当它从API获得一些null值时。即"Fax": null然后应用程序崩溃,因为它无法使用以下行来解析数据

let data = try JSONDecoder().decode(dataModel.self, from: dataSet)

什么是定义模型的最佳方法,因此我不需要拆开可选参数或给它提供默认值。

ios swift xcode codable decodable
3个回答
2
投票

您可以使用默认值实现自定义解码器:

class CompanyInfo : Codable {
    var NameEn: String
    var CityEn: String
    var Website: String
    var Email: String
    var Phone: String
    var Fax: String

    required init(from decoder: Decoder) throws {
        do {
            let container = try decoder.container(keyedBy: CodingKeys.self)
            self.NameEn = try container.decodeIfPresent(String.self, forKey: .NameEn) ?? "Default"
            self.CityEn = try container.decodeIfPresent(String.self, forKey: .CityEn) ?? "Default"
            self.Website = try container.decodeIfPresent(String.self, forKey: .Website) ?? "Default"
            self.Email = try container.decodeIfPresent(String.self, forKey: .Email) ?? "Default"
            self.Phone = try container.decodeIfPresent(String.self, forKey: .Phone) ?? "Default"
            self.Fax = try container.decodeIfPresent(String.self, forKey: .Fax) ?? "Default"
        }
    }
}

与问题无关,但重要的注意事项:

在Swift中,只有Types名称应以大写字母开头。如果继续这样命名变量,那么如果您决定使用CoreData或与其他Swift开发人员一起工作,则有一天会遇到严重的重构问题。


0
投票

如果数据模型反映了API的JSON响应(“不要让我思考”),任何未来的同事都会感谢您。此外,现在您不希望拥有可选值-在3周内可能需要它们-然后您会进行一些丑陋的检查:

if companyInfo.fax == "default" {
   // Hey it's the default value but this indicates that the value is optional and nil
}

但是,这是可行的:

https://developer.apple.com/documentation/foundation/archives_and_serialization/encoding_and_decoding_custom_types

顺便说一句-也请阅读有关属性名称的Swift命名约定。

https://swift.org/documentation/api-design-guidelines/


-1
投票

没有这样的答案可以更有效地使用classstruct。这取决于您的需求,应用程序的需求及其编码结构。

如果您必须在运行时处理可选选项,那么对我来说这可能是最好的方法。

我希望在此上使用struct

struct YOUR_MODEL_NAME : Codable {

    var NameEn : String?
    var CityEn : String?
    var Website : String?
    var Email : String?
    var Phone : String?
    var Fax : String?

    enum CodingKeys: String, CodingKey {
        case NameEn = "YOUR_KEY_FOR_NameEn"
        case CityEn = "YOUR_KEY_FOR_CityEn"
        case Website = "YOUR_KEY_FOR_Website"
        case Email = "YOUR_KEY_FOR_Email"
        case Phone = "YOUR_KEY_FOR_Phone"
        case Fax = "YOUR_KEY_FOR_Fax"
    }

    init(from decoder: Decoder) throws {
        let values = try decoder.container(keyedBy: CodingKeys.self)
        NameEn = try values.decodeIfPresent(String.self, forKey: .NameEn)
        CityEn = try values.decodeIfPresent(String.self, forKey: .CityEn)
        Website = try values.decodeIfPresent(String.self, forKey: .Website)
        Email = try values.decodeIfPresent(String.self, forKey: .Email)
        Phone = try values.decodeIfPresent(String.self, forKey: .Phone)
        Fax = try values.decodeIfPresent(String.self, forKey: .Fax)
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.