Reputation: 13
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
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
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