Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/94.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 迭代Firebase中节点中的所有节点_Ios_Uitableview_Firebase_Swift3_Firebase Realtime Database - Fatal编程技术网

Ios 迭代Firebase中节点中的所有节点

Ios 迭代Firebase中节点中的所有节点,ios,uitableview,firebase,swift3,firebase-realtime-database,Ios,Uitableview,Firebase,Swift3,Firebase Realtime Database,我得到的示例结构如下所示: 我想将每个项目添加到我创建的项目数组中。如你所见,downloadListData函数只能从苹果下载信息,因为我不知道如何在不编写大量代码的情况下同时获得苹果、面包和鸡蛋。我在尝试循环和数组,但没有成功。此外,我在互联网上分析示例,但没有得到在我的应用程序中有效的答案 ListItem.swift: import Foundation import Firebase struct ListItem{ var name : String! var a

我得到的示例结构如下所示:

我想将每个项目添加到我创建的项目数组中。如你所见,downloadListData函数只能从苹果下载信息,因为我不知道如何在不编写大量代码的情况下同时获得苹果、面包和鸡蛋。我在尝试循环和数组,但没有成功。此外,我在互联网上分析示例,但没有得到在我的应用程序中有效的答案

ListItem.swift:

import Foundation
import Firebase

struct ListItem{
    var name : String!
    var addedBy : String!
    var completed : Bool!

    init(name: String, addedBy: String, completed: Bool){
        self.name = name
        self.addedBy = addedBy
        self.completed = completed
    }
}
my ViewController.swift的一部分:

import UIKit
import Firebase

class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {

    var rootRef : FIRDatabaseReference!
    var listDataRef : FIRDatabaseReference!

    var refHandle: UInt!

    var listItemsDownload = [ListItem]()

    //test vars
    var user : String!

    @IBOutlet weak var plusButton: UIButton!
    @IBOutlet weak var tableView: UITableView!

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.

        tableView.delegate = self
        tableView.dataSource = self
        user = "test@me.com"


        rootRef = FIRDatabase.database().reference()
        listDataRef = rootRef.child("listData")            

        downloadListData()
    }

func numberOfSections(in tableView: UITableView) -> Int {
    return 1
}

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return listItemsDownload.count
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    if let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as? CellData{

        print("cellForRowAt")
        let items = listItemsDownload[indexPath.row]
        // testing the tableView            
        cell.nameLabel?.text = items.name

        }
        return cell
    } else{
        print("else")
        return CellData()
    }
}
func downloadListData(){
    print(" ### DOWNLOAD ###")
    self.listDataRef.observe(FIRDataEventType.value, with: { snapshot in
        var downloadedName : String!
        var downloadedUser : String!
        var downloadedComplete : Bool!

        if let dict = snapshot.value as? Dictionary<String, Any>{
            if let apples = dict["Apples"] as? Dictionary<String, Any>{

                if let name = apples["name"] as? String{
                    downloadedName = name
                }

                if let user = apples["addedBy"] as? String{
                    downloadedUser = user
                }

                if let completed = apples["completed"] as? Bool{
                    downloadedComplete = completed
                }

                let item = ListItem(name: downloadedName, addedBy: downloadedUser, completed: downloadedComplete)

                self.listItemsDownload.append(item)

                self.tableView.reloadData()

            }
        }
    })
}
导入UIKit
进口火基
类ViewController:UIViewController、UITableViewDelegate、UITableViewDataSource{
var rootRef:FIRDatabaseReference!
变量listDataRef:FIRDatabaseReference!
变量refHandle:UInt!
var listItemsDownload=[ListItem]()
//测试变量
var用户:字符串!
@IBVAR弱脉冲按钮:UIButton!
@IBVAR表格视图:UITableView!
重写func viewDidLoad(){
super.viewDidLoad()
//加载视图后,通常从nib执行任何其他设置。
tableView.delegate=self
tableView.dataSource=self
用户=”test@me.com"
rootRef=FIRDatabase.database().reference()
listDataRef=rootRef.child(“listData”)
下载列表数据()
}
func numberOfSections(在tableView:UITableView中)->Int{
返回1
}
func tableView(tableView:UITableView,numberofrowsinssection:Int)->Int{
返回listItemsDownload.count
}
func tableView(tableView:UITableView,cellForRowAt indexath:indexPath)->UITableViewCell{
如果let cell=tableView.dequeueReusableCell(标识符为“cell”,for:indexPath)作为?CellData{
打印(“cellForRowAt”)
让items=listItemsDownload[indexPath.row]
//测试tableView
cell.namelab?.text=items.name
}
返回单元
}否则{
打印(“其他”)
返回CellData()
}
}
func下载列表数据(){
打印(“下载”)
self.listDataRef.observe(FIRDataEventType.value,带:{snapshot in
var下载名称:String!
var下载用户:String!
var下载完成:Bool!
如果让dict=snapshot.value作为字典{
如果让apples=dict[“apples”]作为字典{
如果让name=apples[“name”]作为字符串{
downloadedName=名称
}
如果let user=apples[“addedBy”]作为字符串{
下载用户=用户
}
如果让已完成=苹果[“已完成”]as?Bool{
下载完成=完成
}
let item=ListItem(名称:downloadedName,添加人:downloadedUser,已完成:downloadedComplete)
self.listItemsDownload.append(项目)
self.tableView.reloadData()
}
}
})
}

因此,我可能只需要更改这一行以获得不同的值,而不仅仅是苹果(
如果让苹果=dict[“苹果”]as?Dictionary{

只需使用一个单独的方法,您可以使用不同的键调用它,如下所示:

  func downloadListData(){
    print(" ### DOWNLOAD ###")
    self.listDataRef.observe(FIRDataEventType.value, with: { snapshot in
        addAllItemsFromSnapshotWithKey(snapshot, key: "Apples")
        addAllItemsFromSnapshotWithKey(snapshot, key: "Bread")
        addAllItemsFromSnapshotWithKey(snapshot, key: "Eggs")
        // You need to reload your table view on the main thread, since it's an asynchronous call to firebase
        DispatchQueue.main.async {
          self.tableView.reloadData()  
        }
    })
  }

  func addAllItemsFromSnapshotWithKey(_ snapshot: FIRDataSnapshot, key: String) {
    var downloadedName : String!
    var downloadedUser : String!
    var downloadedComplete : Bool!

    if let dict = snapshot.value as? Dictionary<String, Any>{
      if let values = dict[key] as? Dictionary<String, Any> {

        if let name = values["name"] as? String{
          downloadedName = name
        }

        if let user = values["addedBy"] as? String{
          downloadedUser = user
        }

        if let completed = values["completed"] as? Bool{
          downloadedComplete = completed
        }

        let item = ListItem(name: downloadedName, addedBy: downloadedUser, completed: downloadedComplete)

        self.listItemsDownload.append(item)

      }
    }
  }
func下载列表数据(){
打印(“下载”)
self.listDataRef.observe(FIRDataEventType.value,带:{snapshot in
使用键添加快照中的所有项(快照,键:“苹果”)
使用键添加快照中的所有项(快照,键:“面包”)
使用键添加快照中的所有项(快照,键:“鸡蛋”)
//您需要在主线程上重新加载表视图,因为它是对firebase的异步调用
DispatchQueue.main.async{
self.tableView.reloadData()
}
})
}
func addAllItemsFromSnapshotWithKey(snapshot:FIRDataSnapshot,key:String){
var下载名称:String!
var下载用户:String!
var下载完成:Bool!
如果让dict=snapshot.value作为字典{
如果let values=dict[key]as?字典{
如果让name=值[“name”]作为字符串{
downloadedName=名称
}
如果让用户=值[“addedBy”]作为字符串{
下载用户=用户
}
如果let completed=值[“completed”]as?Bool{
下载完成=完成
}
let item=ListItem(名称:downloadedName,添加人:downloadedUser,已完成:downloadedComplete)
self.listItemsDownload.append(项目)
}
}
}
更新以获得更具可扩展性的解决方案。只需遍历所有键即可

 func downloadListData(){
    print(" ### DOWNLOAD ###")
    self.listDataRef.observe(FIRDataEventType.value, with: { snapshot in
      var downloadedName : String!
      var downloadedUser : String!
      var downloadedComplete : Bool!

      if let dict = snapshot.value as? Dictionary<String, Any>{

        for key in dict.keys {

          if let values = dict[key] as? Dictionary<String, Any> {

            if let name = values["name"] as? String{
              downloadedName = name
            }

            if let user = values["addedBy"] as? String{
              downloadedUser = user
            }

            if let completed = values["completed"] as? Bool{
              downloadedComplete = completed
            }

            let item = ListItem(name: downloadedName, addedBy: downloadedUser, completed: downloadedComplete)

            self.listItemsDownload.append(item)
          }
        }
        DispatchQueue.main.async {
          self.tableView.reloadData()
        }
      }
    })
  }
func下载列表数据(){
打印(“下载”)
self.listDataRef.observe(FIRDataEventType.value,带:{snapshot in
var下载名称:String!
var下载用户:String!
var下载完成:Bool!
如果让dict=snapshot.value作为字典{
对于dict.keys中的键{
如果let values=dict[key]as?字典{
如果让name=值[“name”]作为字符串{
downloadedName=名称
}
如果让用户=值[“addedBy”]作为字符串{
下载用户=用户
}
如果let completed=值[“completed”]as?Bool{
下载完成=完成
}
let item=ListItem(名称:downloadedName,添加人:downloadedUser,已完成:downloadedComplete)
self.listItemsDownload.append(项目)
}
}
DispatchQueue.main.async{
self.tableView.reloadData()
}
}
})
}

好的,但是如果我有更多的数据怎么办?这似乎不是一个非常可扩展的解决方案。更新了我的答案@coddder123