Reputation: 384
I'm using Swift and Firestore, where I have collection of tasks.
I populate each tableview cell with a task data. There is a field hashtags. Now it's just a string, but I want it to be an array of strings.
How can I save array of strings in Task model and correctly display it in the tableview?
My Task model file:
import Foundation
import FirebaseFirestore
protocol DocumentSerializable {
init?(dictionary:[String:Any])
}
struct Task {
var title: String
var description: String
var tip: String
var hashtags: String
var dictionary:[String:Any] {
return [
"title": title,
"description": description,
"tip": tip,
"hashtags": hashtags
]
}
}
extension Task : DocumentSerializable {
init?(dictionary: [String : Any]) {
let title = dictionary["title"] as? String ?? "Error! Title Field Not Found!"
let description = dictionary["description"] as? String ?? "Error! Description Field Not Found!"
let tip = dictionary["tip"] as? String ?? "Error! Tip Field Not Found!"
let hashtags = dictionary["hashtags"] as? String ?? "Error! Hashtags Field Not Found!"
self.init(title: title, description: description, tip: tip, hashtags: hashtags)
}
}
My TableViewViewController file:
import UIKit
import Firebase
import FirebaseAuth
import FirebaseFirestore
class TasksListScreen: UIViewController {
var db = Firestore.firestore()
var tasksArray = [Task]()
@IBOutlet weak var tableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
loadData()
}
// load data from the user tasks collection to the table view
func loadData() {
let userID = Auth.auth().currentUser!.uid
let userTasksCollRef = db.collection("users").document(userID).collection("tasks")
userTasksCollRef.getDocuments { (queryShapshot, error) in
if let error = error {
print("Error loading data: \(error.localizedDescription)")
} else {
self.tasksArray = queryShapshot!.documents.compactMap({Task(dictionary: $0.data())})
DispatchQueue.main.async {
self.tableView.reloadData()
}
}
}
}
}
extension TasksListScreen: UITableViewDataSource, UITableViewDelegate {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return tasksArray.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "taskCell") as! TaskViewCell
let task = tasksArray[indexPath.row]
cell.previewTitleLabel.text = task.title
cell.previewMotivLabel.text = task.description
cell.previewTipLabel.text = task.tip
cell.previewHashtagsLabel.text = task.hashtags
cell.cellDelegate = self
cell.index = indexPath
return cell
}
}
Upvotes: 0
Views: 356
Reputation: 16341
Firstly, You should modify the hashtags
property in Task
and the init?(dictionary:)
method. Like this:
struct Task {
var title: String
var description: String
var tip: String
var hashtags: [String]
var dictionary:[String: Any] {
return [
"title": title,
"description": description,
"tip": tip,
"hashtags": hashtags
]
}
}
extension Task: DocumentSerializable {
init?(dictionary: [String : Any]) {
let title = dictionary["title"] as? String ?? "Error! Title Field Not Found!"
let description = dictionary["description"] as? String ?? "Error! Description Field Not Found!"
let tip = dictionary["tip"] as? String ?? "Error! Tip Field Not Found!"
let hashtags = dictionary["hashtags"] as? [String] ?? ["Error! Hashtags Field Not Found!"]
self.init(title: title, description: description, tip: tip, hashtags: hashtags)
}
}
Then you need to modify the cellForRow method's following line to pass the array and display it properly.
Modify this:
cell.previewHashtagsLabel.text = task.hashtags
To:
cell.handleHashTags(task.hashtags)
You need to add a new method in TaskViewCell
class named handleHashTags
and handle the array of strings [String]
passed to display them.
Upvotes: 1