繁体   English   中英

如何知道使用哪个初始化程序来读取数据(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
    ]
}

}

为了读取最新数据,我将此方法与 first 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)
            }

为什么以及何时需要使用第二个 init?

在有关 raywenderlich.com 的 Firebase 教程中,我们了解了以下示例:使用第二个 init 将数据同步到表视图:

    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...

然后将该原始数据传递给结构。 然后将 object 添加到数组中

在第二种情况下,快照本身被传递给结构

init?(snapshot:DataSnapshot) {
    guard let value = snapshot.value as? [String:AnyObject],

快照被分解为 object 中的原始数据。

两者 function 相同。

这是可读性和个人喜好的问题。 一般来说,在 object 中包含初始化程序等可以使代码更具可读性,object 更可重用且代码更少 - 请参阅此伪代码

DataObjects.infoRef.child(uid!).observe(.value){ snapshot, error in
    let user = UserInfo(snapshot)
    self.newArray.append(user)
})

这是非常紧凑的代码。

想象一下,如果您想在应用程序中访问这些对象的 10 个地方。 在您的第一种情况下,该代码必须复制 10 次——这可能需要更多的故障排除。 在我上面的示例中,object 本身完成了繁重的工作,因此访问它们需要的代码要少得多。

另外两件事。 您可能需要考虑使用 .childSnapshot 来访问快照而不是字典中的数据(无论哪种方式都有效)

let userName = snapshot.childSnapshot(forPath: "name").value as? String ?? "No Name"

请避免强制展开可选变量

child(uid!)

因为它会导致不稳定的代码和随机的、无法解释的崩溃。 这会更好

guard let uid = maybeUid else { return } //or handle the error

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM