![](/img/trans.png)
[英]Is it possible to create an optional and non-optional version of a swift protocol dynamically?
[英]Best approach to create Non-optional Codable with `default values` in swift
我知道class
和struct
的基本概念,但它更有效地為 API 創建模型以獲取數據並告訴我優缺點。
以前我不使用可選的模型。 相反,我給它一些價值。 IE
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)
定義 model 的最佳方法是什么,所以我不需要解開可選或給它默認值。
您可以使用默認值實現自定義解碼器:
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 開發人員合作,那么有一天你會遇到嚴重的重構問題。
如果數據 model 反映了 API 的 JSON 響應(“不要讓我思考”),任何未來的同事都會感謝您。 此外,現在你不希望有可選值——在 3 周內你可能需要它們——然后你有一些丑陋的檢查:
if companyInfo.fax == "default" {
// Hey it's the default value but this indicates that the value is optional and nil
}
但是,這是可行的:
順便說一句 - 還閱讀有關屬性名稱的 Swift 命名約定。
對於更有效地使用class
或struct
,沒有這樣的答案。 這取決於您的需求、應用程序的需求及其編碼結構。
如果您必須在運行時處理選項,這可能是我認為的最佳方法。
我寧願在這個上使用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)
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.