Запрашиваемый документ Firestore имеет тип [String: Any]
, поэтому настройте инициализатор так, чтобы он принимал такой словарь. Поскольку вы работаете с возвратом из базы данных, никогда не гарантируется, что данные будут полностью сохранены; сетевые ошибки и ошибки базы данных могут вернуть отсутствующие или поврежденные данные. Поэтому рекомендуется отключить инициализатор - это просто означает, что он может вернуть nil
(может произойти сбой).
Я взял ваш пример и сделал свойство email
необязательным, просто чтобы показать вам, как это будет выглядеть. В приведенном ниже примере только три из четырех свойств необходимы для создания экземпляра объекта User
.
let info: [String: Any] = ["hasFriends": true]
let firestoreData: [String: Any] = ["firstName": "lance", "lastName": "stevenson", "userName": "lstevenson", "info": info]
struct User {
var firstName: String
var lastName: String
var userName: String
var info: [String: Any]
var email: String?
var hasFriends: Bool
init?(data: [String: Any]) {
guard let firstName = data["firstName"] as? String,
let lastName = data["lastName"] as? String,
let userName = data["userName"] as? String,
let info = data["info"] as? [String: Any],
let hasFriends = info["hasFriends"] as? Bool else {
return nil
}
self.firstName = firstName
self.lastName = lastName
self.userName = userName
self.info = info
self.hasFriends = hasFriends
self.email = data["email"] as? String // User will be created even if this is nil
}
}
if let user = User(data: firestoreData) {
print(user.hasFriends)
}
// prints true
Я бы не советовал использовать для этого инструмент сопоставления Swift, потому что вы, вероятно, будете иметь дело с разными типами значений в одном и том же словаре для разных объектов модели. И код для сопоставления словаря [String: Any]
с этими переменными в инициализаторе не будет красивым, особенно если учесть, что альтернатива (здесь) дает тот же результат со значительно более простым кодом.
Помните, утопия программирования - то, к чему мы все должны стремиться - это выполнять самые мощные вещи с помощью максимально простого кода. Если это не цель, то так и должно быть.