在函数外部获取一个值

问题描述:

你好,我是swift编程的新手,我想从loadData()得到label的值用于我的路径(参考)到我的数据库dbRef!.child(place+"/placeLabel")。我的意思是?!我读取了“Dio Con Dio”节点上的数据。这是因为值placelet place = "Dio Con Dio"。所以,我的应用程序不会加载来自“Paradosiako - Panorama”节点的数据。我想加载数据库中的所有内容,我认为如果我可以将place的值更改为下一个节点,它可以读取所有数据。在函数外部获取一个值

import UIKit 
    import FirebaseDatabase 

    class PlacesTableViewController: UITableViewController { 

     //MARK: Properties 
     @IBOutlet weak var placesTableView: UITableView! 

     //database reference 
     var dbRef:FIRDatabaseReference? 

     var places = [Places]() 

     private var loadedLabels = [String: String]() 
     private var loadedRatings = [String: Int]() 

     //handler 
     var handle:FIRDatabaseHandle? 

     override func viewDidLoad() { 
      super.viewDidLoad() 

      dbRef = FIRDatabase.database().reference() 

      // Loads data to cell. 
      loadData() 
     } 

       private func loadData() { 

       let place = "Dio Con Dio" 

       dbRef!.child(place+"/placeLabel").observe(.childAdded, with: { 
        (snapshot) in 
        let label = snapshot.value as! String 
        self.updatePlace(snapshot.key, label: label) 
       }) 
       dbRef!.child(place+"/rating").observe(.childAdded, with: { 
        (snapshot) in 
        let rating = snapshot.value as! Int 
        self.updatePlace(snapshot.key, rating: rating) 
       }) 


      } 

      private func updatePlace(_ key: String, label: String? = nil, rating: Int? = nil) { 
       if let label = label { 
        loadedLabels[key] = label 
       } 
       if let rating = rating { 
        loadedRatings[key] = rating 
       } 
       guard let label = loadedLabels[key], let rating = loadedRatings[key] else { 
        return 
       } 
       if let place = Places(name: label, rating: rating) { 
        places.append(place) 
        placesTableView.reloadData() 
       } 
      } 
     } 

**My Database**

(这个问题是一个跟进from this one。)

+0

为什么不让'label'实例字段或使loadData()返回一个String类型?你也可以将'label'作为'inout'参数。 –

+0

所以你想从e函数获取一个值,然后将它传递给loadData中的标签? –

+0

基本上我想'label'值在它初始化之前,所以我可以在这里使用它:'dbRef!.child(place +“/ placeLabel”)'。我想将'label'值赋给'place'值。 –

为了您数据库模式,试试这个来代替:

private func loadData() { 
    dbRef!.observe(.childAdded) { 
    (placeSnapshot) in 
     print("Adding place \(placeSnapshot.key)...") 

     // Load each label on the "placeLabel" list. 
     let labels = placeSnapshot.childSnapshot(forPath: "placeLabel") 
     for (key, label) in labels.value as! [String: String] { 
      self.updatePlace(key, label: label) 
     } 

     // Load each rating in the "rating" list. 
     let ratings = placeSnapshot.childSnapshot(forPath: "rating") 
     for (key, rating) in ratings.value as! [String: Int] { 
      self.updatePlace(key, rating: rating) 
     } 
    } 
} 

updatePlace功能简单标签组和评级属性,这些地址是由loadData单独加载的。

地方删除。当然,上面的代码不会处理地方删除。为此,您还需要听取childRemoved事件。

+0

“Dio Con Dio”,“Paradosiako - Panorama”是现实生活中的地名。 它的工作原理,但每次我在数据库中添加一个新的地名时都会出错。假设已经有一个评级,placeLabel和Dio Con Dio的评论。如果有人在我的数据库中为Dio Con Dio添加了额外评分,评论和placeLabel,它不会崩溃。现在,如果我删除了所有Dio Con Dio评论,评分和placeLabels以及某人将首次为Dio Con Dio添加评论,评分和placeLabel,它会崩溃,但会在我的数据库上创建该节点。你到底懂不懂呢? –

+0

[这是错误。](http://prntscr.com/f8hoap)我没有与以前的代码错误。但你明白我想做什么! –

+0

这个错误是因为你的钥匙是空的,你用“!”强制匹配你只应该尝试获得值,如果你的密钥不是零和不为空(“”) – Mozahler

在评论中很难解释这一点,所以我会在这里解决你当前的问题,但是保罗回答你的问题,我相信。你甚至可以在这个问题上开一个新的问题。

这里是您遇到的问题的代码:

for (key, rating) in ratings.value as! [String: Int] { 
      self.updatePlace(key, rating: rating) 
     } 

有没有错码的,只要ratings.value充满字符串:整数对。您的错误发生是因为某个键丢失。 (运行时发现了一个NSNull,因此不能将数据转换为一个字典)

您需要设置一个断点,你正在构建数组中:

placeSnapshot.childSnapshot(forPath: "rating") 

(这是这里叫做评级/本地)。如果可以忽略没有键的条目,则跳过它们,不要将它们追加到您的数组中。但它更有可能你有一个错误,需要找出你为什么要添加一个空值...

这是否更有意义?如果他解决了一个问题,请接受Paulo的回答,并用关于childSnapshot(代码)的更多信息开启一个新问题,并且有人会确定帮助你。 (我知道我会试试。)

+0

感谢您花时间对我的答案进行跟进。你的分析似乎对我很重要:-) –

+0

@Mozahler我明白你的答案,谢谢。 [我提出了一个新问题](http://stackoverflow.com/questions/44023455/retrieve-from-firebase-database-calculating-平均) –