Let me be precise and clear with original code: Originally I have 3 view controllers
- SearchResultsScreenViewController (Main VC)
- GuidesListSearchScreenViewController (First Container VC)
- ServicesListSearchScreenViewController (Second Container VC)
In the Main VC i used a segmented control to see container vc’s on screen, here:
import UIKit
import Firebase
class SearchResultsScreenViewController: UIViewController
{
@IBOutlet weak var GuideListView: UIView!
@IBOutlet weak var ServicesListView: UIView!
var searchQueryKeyword: String?
var guidesDataArray = [GuideDM]()
override func viewDidLoad()
{
super.viewDidLoad()
ServicesListView.isHidden = true
populateGuidesList()
}
@IBAction func SegmentChanged(_ sender: UISegmentedControl)
{
switch sender.selectedSegmentIndex
{
case 0:
GuideListView.isHidden = false
ServicesListView.isHidden = true
break
case 1:
GuideListView.isHidden = true
ServicesListView.isHidden = false
break
default:
break
}
}
func populateGuidesList()
{
let dbRef = Firestore.firestore().collection("guide")
dbRef.getDocuments
{ (snapshot, error) in
if let err = error
{
print(err.localizedDescription)
print("Error: Unable to find guides list")
}
else
{
if let snap = snapshot
{
print("List is started now")
for doc in snap.documents
{
if doc.exists
{
let data = doc.data()
let city = data["city"] as? String ?? ""
let province = data["province"] as? String ?? ""
let country = data["country"] as? String ?? ""
if city.localizedCaseInsensitiveContains(self.searchQueryKeyword!) || province.localizedCaseInsensitiveContains(self.searchQueryKeyword!) || country.localizedCaseInsensitiveContains(self.searchQueryKeyword!)
{
let guideId = doc.documentID
let guideEmail = data["email"] as? String ?? ""
let name = data["name"] as? String ?? ""
let dob = data["dob"] as? String ?? ""
let feeCurrency = data["feeCurrency"] as? String ?? ""
let status = data["status"] as? String ?? ""
let totalReviews = data["totalReviews"] as? Int ?? 0
let rating = data["rating"] as? Int ?? 0
let baseFee = data["baseFee"] as? Int ?? 0
let isGuideFeatured = data["isGuideFeatured"] as? Bool ?? false
//make a model of guide and append in array
let guide = GuideDM(id: guideId, email: guideEmail, name: name, dob: dob, city: city, province: province, country: country, feeCurrency: feeCurrency, status: status, baseFee: baseFee, rating: rating, totalReviews: totalReviews, isGuideFeatured: isGuideFeatured)
self.guidesDataArray.append(guide)
}
}
}
print("list is finalized now")
}
}
}
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?)
{
if segue.identifier == "searchScreentoGuideListSegment"
{
let guidesListContainerVC = segue.destination as! GuidesListSearchScreenViewController
guidesListContainerVC.guidesDataArray = self.guidesDataArray
}
}
}
In the above class my code makes a call to function “populateGuidesList()” which makes a network call to get data from firebase, and at the same time loads up my container views. The problem is, before the network call returns data, the empty array gets passed to my “GuidesListSearchScreenViewController” i.e. (First container VC), which is a table view, and loads an empty table because the array is not filled yet.
My First container VC class:
import UIKit
import Firebase
class GuidesListSearchScreenViewController: UIViewController
{
@IBOutlet weak var guidesListTableView: UITableView!
var guidesDataArray = [GuideDM]()
override func viewDidLoad()
{
super.viewDidLoad()
guidesListTableView.delegate = self
guidesListTableView.dataSource = self
guidesListTableView.register(UINib(nibName: "GuidesListCellSearchScreenTableViewCell", bundle: nil), forCellReuseIdentifier: "guidesListCell")
}
}
extension GuidesListSearchScreenViewController: UITableViewDataSource, UITableViewDelegate
{
// below functions are to setup the table view
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
return guidesDataArray.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{
let cell = guidesListTableView.dequeueReusableCell(withIdentifier: "guidesListCell") as! GuidesListCellSearchScreenTableViewCell
//adding properties to cell and then returning cell
return cell
}
}
GOAL: Either load the container view, after the data is received in the array, or refresh the table by again passing the array to container VC and reloading table.
Other solution: I had tried loading up all this array data inside First container VC class, and reloading table view data from there, which works perfectly fine, but to me which is a very inefficient approach, as i need this array in both container views, so making network calls for each container vc seems very inefficient. Therefore, i am trying to get the data once and pass in both container views. Kindly correct me if you feel me wrong.
P.s I have deleted other functionality and simplified the code. And help would be highly appreciated.