我正在尝试将从Firestore数据库中检索到的“用户”映射到我在代码中定义的用户结构,但是我认为我不能迅速正确地理解映射功能。
如何将检索到的用户映射到结构中?
结构
struct User {
// Properties
var firstName: String
var lastName: String
var userName: String
var email: String
init(firstName: String, lastName: String, userName: String, email: String) {
self.firstName = firstName
self.lastName = lastName
self.userName = userName
self.email = email
}
}
从Firestore获取用户的功能
func getUser(UID: String) {
// Firebase setup
settings.areTimestampsInSnapshotsEnabled = true
db.settings = settings
db.collection("users").document(UID).getDocument { (document, error) in
if let error = error {
print("Error: \(error.localizedDescription)")
} else {
print(document!.data()!)
}
}
}
答案 0 :(得分:1)
查询的Firestore文档的类型为DeviceIoControl(hDisk, FSCTL_ALLOW_EXTENDED_DASD_IO, NULL, 0, NULL, 0, &dwBytesRead, NULL);
,因此,请将您的初始化程序配置为接受这种字典。因为您正在使用数据库返回,所以无法保证数据将完全完整。网络错误和数据库错误会返回丢失或损坏的数据。因此,使初始化程序失败是一个好主意-这只是意味着它可以返回[String: Any]
(失败)。
我以您的示例为例,将nil
属性设为可选,只是向您展示了它的外观。在下面的示例中,实例化email
对象的四个属性中只有三个是必需的。
User
我不建议您为此使用Swift的映射工具,因为您可能会在同一个字典中处理不同模型对象的不同类型的值。而且将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
字典与这些变量在初始值设定项中映射的代码将不是很漂亮-特别是考虑到替代方法(此处)使用相当简单的代码会产生相同的结果。
请记住,编程的乌托邦-我们都应该争取-用最简单的代码执行最强大的功能。如果那不是目标,那应该是。