2017-05-13 42 views
2

你好,我是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'值。 –

回答

2

爲了您數據庫模式,試試這個來代替:

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

3

在評論中很難解釋這一點,所以我會在這裏解決你當前的問題,但是保羅回答你的問題,我相信。你甚至可以在這個問題上開一個新的問題。

這裏是您遇到的問題的代碼:

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-平均) –