如何知道使用哪个初始化器来读取数据(Firebase)
How to know which initializer to use for reading data(Firebase)
我有两个初始化程序:
struct UserInfo{
let ref: DatabaseReference?
let key: String
let firstName: String
let lastName: String
let username: String
let pictureURL : String?
let admin : Bool
init(firstName: String, lastName:String,username:String,pictureURL:String?,admin:Bool, key:String = "" ){
self.ref = nil
self.key = key
self.firstName = firstName
self.lastName = lastName
self.username = username
self.pictureURL = pictureURL
self.admin = admin
}
init?(snapshot:DataSnapshot){
guard let value = snapshot.value as? [String:AnyObject],
let firstName = value["firstName"] as? String,
let lastName = value["lastName"] as? String,
let username = value["userName"] as? String,
let profilePic = value["pictureURL"] as? String,
let admin = value["isAdmin"] as? Bool
else {return nil}
self.ref = snapshot.ref
self.key = snapshot.key
self.firstName = firstName
self.lastName = lastName
self.username = username
self.pictureURL = profilePic
self.admin = admin
}
func toAnyObject()-> Any{
return [
"firstName": firstName,
"lastName": lastName,
"username": username,
"pictureURL":pictureURL as Any,
"isAdmin": admin
]
}
}
为了读取最新数据,我将此方法与第一个 init 结合使用并且有效:
let completed =
DataObjects.infoRef.child(uid!).observe(.value){ snapshot,error in
var newArray: [UserInfo] = []
if let dictionary = snapshot.value as? [String:Any]{
let username = dictionary["username"] as! String
let firstName = dictionary["firstName"] as! String
let lastName = dictionary["lastName"] as! String
let profilePic = dictionary["pictureURL"] as? String
let admin = dictionary["isAdmin"] as! Bool
let userInformation = UserInfo(firstName: firstName, lastName:
lastName, username: username,pictureURL: profilePic, admin: admin)
newArray.append(userInformation)
print(newArray)
completion(.success(newArray))
print(newArray)
}
为什么以及什么时候需要使用第二个初始化?
在 raywenderlich.com 的 Firebase 教程中,我们举了一个例子:使用第二个初始化将数据同步到 Table 视图:
let completed = ref.observe(.value) { snapshot in
// 2
var newItems: [GroceryItem] = []
// 3
for child in snapshot.children {
// 4
if
let snapshot = child as? DataSnapshot,
let groceryItem = GroceryItem(snapshot: snapshot) {
newItems.append(groceryItem)
}
}
// 5
self.items = newItems
self.tableView.reloadData()
但我的方法和第一个初始化一样。
这个问题实际上是在问两个功能相同的东西。
在一种情况下,快照在 firebase 闭包中被“分解”为其原始数据(字符串等)
DataObjects.infoRef.child(uid!).observe(.value){ snapshot,error in
let username = dictionary["username"] as! String
let firstName = dictionary["firstName"] as! String
let lastName = dictionary["lastName"] as! String
let userInformation = UserInfo(firstName: firstName, lastName: lastName...
然后将该原始数据传递给结构。然后将该对象添加到数组
在第二种情况下,快照本身被传递给结构
init?(snapshot:DataSnapshot) {
guard let value = snapshot.value as? [String:AnyObject],
并且快照被分解为对象内的原始数据。
两者功能相同
这是可读性和个人喜好的问题。一般来说,在一个对象中包含初始化器等可以使代码更具可读性,对象更可重用,代码更少 - 请参阅此伪代码
DataObjects.infoRef.child(uid!).observe(.value){ snapshot, error in
let user = UserInfo(snapshot)
self.newArray.append(user)
})
这是非常紧凑的代码。
想象一下,如果您希望在应用程序中的 10 个位置访问这些对象。在您的第一种情况下,该代码必须被复制 10 次——这可能需要更多的故障排除。在我上面的示例中,对象本身承担了繁重的工作,因此访问它们需要的代码要少得多。
另外两件事。您可能需要考虑使用 .childSnapshot 来访问快照中的数据而不是字典(无论哪种方式都有效)
let userName = snapshot.childSnapshot(forPath: "name").value as? String ?? "No Name"
并且请避免强制展开可选变量
child(uid!)
因为它会导致不稳定的代码和随机的、无法解释的崩溃。这样会更好
guard let uid = maybeUid else { return } //or handle the error
我有两个初始化程序:
struct UserInfo{
let ref: DatabaseReference?
let key: String
let firstName: String
let lastName: String
let username: String
let pictureURL : String?
let admin : Bool
init(firstName: String, lastName:String,username:String,pictureURL:String?,admin:Bool, key:String = "" ){
self.ref = nil
self.key = key
self.firstName = firstName
self.lastName = lastName
self.username = username
self.pictureURL = pictureURL
self.admin = admin
}
init?(snapshot:DataSnapshot){
guard let value = snapshot.value as? [String:AnyObject],
let firstName = value["firstName"] as? String,
let lastName = value["lastName"] as? String,
let username = value["userName"] as? String,
let profilePic = value["pictureURL"] as? String,
let admin = value["isAdmin"] as? Bool
else {return nil}
self.ref = snapshot.ref
self.key = snapshot.key
self.firstName = firstName
self.lastName = lastName
self.username = username
self.pictureURL = profilePic
self.admin = admin
}
func toAnyObject()-> Any{
return [
"firstName": firstName,
"lastName": lastName,
"username": username,
"pictureURL":pictureURL as Any,
"isAdmin": admin
]
}
}
为了读取最新数据,我将此方法与第一个 init 结合使用并且有效:
let completed =
DataObjects.infoRef.child(uid!).observe(.value){ snapshot,error in
var newArray: [UserInfo] = []
if let dictionary = snapshot.value as? [String:Any]{
let username = dictionary["username"] as! String
let firstName = dictionary["firstName"] as! String
let lastName = dictionary["lastName"] as! String
let profilePic = dictionary["pictureURL"] as? String
let admin = dictionary["isAdmin"] as! Bool
let userInformation = UserInfo(firstName: firstName, lastName:
lastName, username: username,pictureURL: profilePic, admin: admin)
newArray.append(userInformation)
print(newArray)
completion(.success(newArray))
print(newArray)
}
为什么以及什么时候需要使用第二个初始化?
在 raywenderlich.com 的 Firebase 教程中,我们举了一个例子:使用第二个初始化将数据同步到 Table 视图:
let completed = ref.observe(.value) { snapshot in
// 2
var newItems: [GroceryItem] = []
// 3
for child in snapshot.children {
// 4
if
let snapshot = child as? DataSnapshot,
let groceryItem = GroceryItem(snapshot: snapshot) {
newItems.append(groceryItem)
}
}
// 5
self.items = newItems
self.tableView.reloadData()
但我的方法和第一个初始化一样。
这个问题实际上是在问两个功能相同的东西。
在一种情况下,快照在 firebase 闭包中被“分解”为其原始数据(字符串等)
DataObjects.infoRef.child(uid!).observe(.value){ snapshot,error in
let username = dictionary["username"] as! String
let firstName = dictionary["firstName"] as! String
let lastName = dictionary["lastName"] as! String
let userInformation = UserInfo(firstName: firstName, lastName: lastName...
然后将该原始数据传递给结构。然后将该对象添加到数组
在第二种情况下,快照本身被传递给结构
init?(snapshot:DataSnapshot) {
guard let value = snapshot.value as? [String:AnyObject],
并且快照被分解为对象内的原始数据。
两者功能相同
这是可读性和个人喜好的问题。一般来说,在一个对象中包含初始化器等可以使代码更具可读性,对象更可重用,代码更少 - 请参阅此伪代码
DataObjects.infoRef.child(uid!).observe(.value){ snapshot, error in
let user = UserInfo(snapshot)
self.newArray.append(user)
})
这是非常紧凑的代码。
想象一下,如果您希望在应用程序中的 10 个位置访问这些对象。在您的第一种情况下,该代码必须被复制 10 次——这可能需要更多的故障排除。在我上面的示例中,对象本身承担了繁重的工作,因此访问它们需要的代码要少得多。
另外两件事。您可能需要考虑使用 .childSnapshot 来访问快照中的数据而不是字典(无论哪种方式都有效)
let userName = snapshot.childSnapshot(forPath: "name").value as? String ?? "No Name"
并且请避免强制展开可选变量
child(uid!)
因为它会导致不稳定的代码和随机的、无法解释的崩溃。这样会更好
guard let uid = maybeUid else { return } //or handle the error