Jonathan-James .M
Jonathan-James .M

Reputation: 13

How to populate a TableView with retrieved data from a Firestore collection using Swift3

I'm really new to IOS development using swift (and coding in general), I would like to know how to populate my tableview cells with data I have retrieved from a Firestore document.

The app Im working on is a personal project for practice, its a basic news app that will load documents from a firestore collection. The collection Im trying to load information from is called "news"

First heres what I have managed to accomplish so far:

//So first I have a struct                

struct Jobs {
var title:String
var description:String 
}

class JobsTableViewController: UITableViewController {

var db:Firestore!
var jobs: Jobs?
var numOfCells = 0



override func viewDidLoad() {
    super.viewDidLoad()
    db = Firestore.firestore()
    loadData()

    DispatchQueue.main.async {
        self.tableView.reloadData()
    }
  }

  func loadData(){


    db.collection("news").getDocuments { (querySnapshot, error) in
        if let error = error
        {
            print("\(error.localizedDescription)")
        }
        else
        {

             for document in (querySnapshot?.documents)!
             {
                if let Title = document.data()["title"] as? String
                {
                    print(Title) //I have this here to see if the new was being retrieved and it was.

                    self.title = Title 
                    self.numOfCells += 1


                }

             }

            DispatchQueue.main.async
            {
                self.tableView.reloadData()
            }

        }
    }

}

    override func numberOfSections(in tableView: UITableView) -> Int {

    return 1
}

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

    return numOfCells
}

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
    cell.textLabel?.text = title
    return cell
}

So when I run the simulator this is my main screen

There are 3 documents in the "news" collection, these three should be displayed in the Jobs TAB when I click on it and it loads (I have the news displayed in the Jobs tab because I first wanted to see if I was ACTUALLY capable of retrieving data, plus I was afraid of messing up the code I already had on News).

When I tab over to the jobs tab (which is where the tableview with our data is), I get something like this

if you noticed the name of my tab bar also changed from Jobs to the title of the document retrived.

In my console it shows all 3 documents have been retrieved

And so my questions are:

1)How do I retrieve ALL my documents into individual cells in the tableview?

2)How do I make it that the tab bar doesn't change its text (as shown above) to the title of my document?

3)What exactly is wrong with my code and why is it wrong and doing what its doing?

4)What improvements can I make to my code and why are they necessary? (Like I said I'm just learning all of this).

Bonus Question:

5)How would I go about having both the title and description appear in a pop up window when a cell is clicked on.

Thank you.

Upvotes: 1

Views: 2017

Answers (2)

Awais Fayyaz
Awais Fayyaz

Reputation: 2415

For this: How would I go about having both the title and description appear in a pop up window when a cell is clicked on?

implement didselectRow delegate function of UITableView

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {

  //retreive job data from array
  let job = jobsArray[inedexPath.row]
  //show an alert with title and description
  showAlert(title: String, desc: String )
}

func showAlert(title: String, desc: String) {

   let alert = UIAlertController(title: title, message: mess, preferredStyle: .alert)
   let okAction = UIAlertAction(title: "Ok", style: .default)
   alert.addAction(okAction)
   self.present(alert, animated: true, completion: nil)

  }

This will show the default alert box of iOS

See more about presenting alert/popups here

how to implement a pop up dialog box in iOS

Or if you want some thing fancy https://github.com/SwiftKickMobile/SwiftMessages

A very flexible message bar for showing popups/alerts supporting swift 4.

Upvotes: 0

Parth Bhuva
Parth Bhuva

Reputation: 877

create an array of jobs globally

var jobsArray = [Jobs]()

fill the array from the db in your load data

for document in (querySnapshot?.documents)! {
    if let Title = document.data()["title"] as? String {
        print(Title) 
        //self.title = Title 
        let job = Jobs()
        job.title = Title

        jobsArray.append(job)
        //self.numOfCells += 1
    }
}

use the array to populate tableview

override func numberOfSections(in tableView: UITableView) -> Int {

    return 1
}

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

    return jobsArray.count
}

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
    let job = jobsArray[inedexPath.row]
    cell.textLabel?.text = job.title
    return cell
}

Upvotes: 3

Related Questions