Ваш код запутывает две разные вещи: инициализацию объекта с набором значений для его элементов и извлечение этих элементов из словаря.Просто напишите два отдельных инициализатора:
import Foundation
struct User {
let uid: String
let username: String
/*
// Due to the absence of an explicit initializer declaration,
// the compiler will synthesize an implicit member-wise initailizer like this:
init(uid: String, username: String) {
self.uid = uid
self.username = username
}
*/
}
extension User {
// Putting this initializer in an extension preserves he member-wise intializer
init?(fromDict dict: [String: Any]) {
guard let uid = dict["uid"] as? String,
let username = dict["username"] as? String
else { return nil }
self.init(uid: uid, username: username)
}
}
struct Offer {
let user: User
let caption: String
let imageURL: String
let creationDate: Date
/*
// Due to the absence of an explicit initializer declaration,
// the compiler will synthesize an implicit member-wise initailizer like this:
init(
user: User,
caption: String,
imageURL: String,
creationDate: Date
) {
self.user = user
self.caption = caption
self.imageURL = imageURL
self.creationDate = creationDate
}
*/
}
extension Offer {
// Putting this initializer in an extension preserves he member-wise intializer
init?(fromDict dict: [String: Any]) {
guard let user = dict["user"] as? User,
let caption = dict["caption"] as? String,
let imageURL = dict["image_url"] as? String,
let secondsFrom1970 = dict["creation_date"] as? Double
else { return nil }
self.init(
user: user,
caption: caption,
imageURL: imageURL,
creationDate: Date(timeIntervalSince1970: secondsFrom1970)
)
}
}
Некоторые примечания:
- Использование оператора nil-coalescing (
??
) для предоставления бессмысленных значений по умолчанию в случае nil
действительно плохая практика.Он скрывает сбои и незаметно вводит проблемы целостности данных;не делайте этого. String
не подходит для члена с именем imageURL
.Используйте URL
. - Если эти указания поступают из JSON, используйте протокол
Codable
для автоматизации всего этого стандартного кода. String
плохой тип для ID
в первую очередь потому, что он очень медленный по сравнению с более подходящими типами, такими как UUID
и Int
.Это особенно верно в большинстве баз данных, где текстовое сравнение на намного медленнее, чем сравнение Int / UUID.