Reputation: 2343
I've got sample structure that looks like this:
I want to add every item to the array of items I've created. So as you can see the downloadListData function can only download information from Apples, because I don't know how to get to Apples, Bread and Eggs in the same time without writing a lot of code. I was trying loops and arrays and it didn't work. Moreovery I was analyzing examples on the Internet and I didn't get the answer which worked in my app.
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
}
}
part of 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 = "[email protected]"
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()
}
}
})
}
So probably I have to change only this line to get to different values and not only Apples (if let apples = dict["Apples"] as? Dictionary<String, Any>{
Upvotes: 1
Views: 411
Reputation: 7324
Just use a separate method which you can call with your different keys like this:
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)
}
}
}
Update for a more scalable solution. Just loop through all keys
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()
}
}
})
}
Upvotes: 2