Класс с хотя бы одним свойством, которое не имеет значения по умолчанию, нуждается в инициализаторе для инициализации этого свойства.
class User {
let name: String
let email: String
}
Класс «Пользователь» не имеет инициализаторов
Когда вы соответствуете Codable
или, более конкретно, Decodable
, как вы хорошо заметили, класс получает синтезированный инициализатор, а именно User.init(from: Decoder)
, который устраняет вышеуказанную проблему. Этот синтезированный инициализатор будет использовать ключи кодирования, названные в соответствии со свойствами.
class User: Decodable { ... }
Как только вы определите перечисление в User
, называемое CodingKeys
(точное имя важно), синтез Decodable
соответствие потребует наличия ключа для каждого свойства . Другими словами, как только один ключ отклоняется от имени свойства, вы должны определить ключ кодирования для каждого свойства.
Следующее делает это и компилирует:
class User: Decodable {
let name: String
let email: String
private enum CodingKeys: String, CodingKey {
case name = "username"
case email
}
}
Если нет указав ключ email
, компилятор не будет знать, как установить это свойство, знает только как разработчик. Следовательно, компилятор не будет синтезировать его для вас, и вам придется.
Там может быть естественное значение по умолчанию, как показано здесь:
class User: Decodable {
let name: String
let email: String
enum CodingKeys: String, CodingKey {
case name = "username"
}
required init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
name = try container.decode(String.self, forKey: .name)
// Default email:
email = "\(name)@example.com"
}
}