I have TableView and every cell contains one reservation fetched from Firestore. I added refresh controller but no data reloads. I don't know where can be a problem. When I changed one reservation status for eg. canceled in Firebase it changes but in tableview after reloads no UI label change to "canceled". I must to display another controller and go back to update UI label in cell.
override func viewDidLoad()
{
super.viewDidLoad()
reservationsTableView.delegate = self
reservationsTableView.dataSource = self
navigationItem.hidesBackButton = true
searchReservations = Reservations
refreshControl.addTarget(self, action: #selector(refresh(send: )), for: UIControl.Event.valueChanged)
reservationsTableView.addSubview(refreshControl)
loadReservations()
}
#objc func refresh(send: UIRefreshControl)
{
DispatchQueue.main.async {
self.loadReservations()
self.refreshControl.endRefreshing()
self.reservationsTableView.reloadData()
}
}
}
func loadReservations()
{
Reservations = []
guard let uid = Auth.auth().currentUser?.uid else { return }
let userCollection = Firestore.firestore().collection("Users")
let thisUserDoc = userCollection.document(uid)
let snapshot = thisUserDoc.collection("Reservations").getDocuments { (querySnapshot, error) in
if let e = error {
print(e)
}
else
{
if let snapshotDocuments = querySnapshot?.documents
{
for doc in snapshotDocuments
{
let data = doc.data()
// let rid = doc.documentID
if let Time = data["Time"] as? String, let Date = data["Date"] as? String, let Guests = data["Guests"] as? String, let RestaurantName = data["RestaurantName"] as? String, let Name = data["Name"] as? String, let Status = data["Status"] as? String, let Phone = data["Phone"] as? String, let Id = data["Id"] as? String, let RestaurantId = data["RestaurantID"] as? String, let Id2 = data["Id2"] as? String, let guestId = data["GuestId"] as? String
{
let newReservation = Reservation(id: Id, userId: guestId, id2: Id2,restaurantId: RestaurantId ,restaurantName: RestaurantName, name: Name, phone: Phone, guests: Guests, time: Time, date: Date, status: Status)
self.Reservations.append(newReservation)
DispatchQueue.main.async {
self.reservationsTableView.reloadData()
}
}
}
}
}
}
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return searchReservations.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: K.reusableCellReservationsC, for: indexPath) as! ReservationCellC
cell.guestName.text = searchReservations[indexPath.row].name
cell.contact.text = searchReservations[indexPath.row].phone
cell.reservationTime.text = searchReservations[indexPath.row].time
cell.reservationDate.text = searchReservations[indexPath.row].date
cell.reservationGuets.text = searchReservations[indexPath.row].guests
cell.reservationStatus.text = searchReservations[indexPath.row].status
cell.cancelBtn.tag = indexPath.row
cell.cancelBtn.addTarget(self, action: #selector(btnCanceledCellTapped(sender: )), for: .touchUpInside)
cell.confirmBtn.addTarget(self, action: #selector(btnConfirmedCellTapped(sender: )), for: .touchUpInside)
cell.lateBtn.addTarget(self, action: #selector(btnLateCellTapped(sender: )), for: .touchUpInside)
return cell
}
What's this line
searchReservations = Reservations
By the way you are appending reservations as below
self.Reservations.append(newReservation)
But you are having row count as
searchReservations.count
This is wrong. It has to be return Reservations.count or you must append values as self.searchReservations.append(newReservation)
Related
I want to connect my TableView to what I query from Firestore. The query works, but I can't get the TableView to show the content. Right now its just a blank tableView. The TableViewCell file also has no issues, since it worked before without the firebase implementation (The Cell is registered correctly).
I suspect that the issue is in cellForRowAt and tried played around in there, but couldn't get anything to work.
Can you find the issue?
import UIKit
import Firebase
class popularViewController: UIViewController, UITableViewDelegate, UITableViewDataSource{
#IBOutlet var table: UITableView!
var texttt = [TextPost]()
override func viewDidLoad() {
super.viewDidLoad()
gettingPosts()
table.register(textTableViewCell.nib(), forCellReuseIdentifier: textTableViewCell.identifier)
table.delegate = self
table.dataSource = self
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(true)
gettingPosts()
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
let alle = models.count + texttt.count
return alle
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: textTableViewCell.identifier, for: indexPath) as! textTableViewCell
cell.configure(with: texttt[indexPath.row])
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 300
}
func gettingPosts(){
let db = Firestore.firestore()
let postsRef = db.collection("posts")
postsRef.addSnapshotListener { (querySnapshot, error) in
guard let snapshot = querySnapshot else {
print("Error fetching snapshots: \(error!)")
return
}
snapshot.documentChanges.forEach { diff in
if (diff.type == .added){
let data = diff.document.data()
let Name = data["username"] as! String
let text = data["description"] as! String
let likes = data["likes"] as! Int
let typ = data["postType"] as! Int
let pfp = data["profileImage"] as! String
let uid = data["uid"] as! String
let pic = data["picture"]
let time = data["time"] as! String
if typ == 0{ // Text post
let dasDing = TextPost(numberOfComments: 0, username: Name, timestampName: time, userImageName: pfp, textName: text)
self.texttt.append(dasDing)
}
}
}
}
}
}
struct TextPost {
let numberOfComments: Int
let username: String
let timestampName: String
let userImageName: String
let textName: String
}
You need to reload data once you get data from firebase
func gettingPosts(){
let db = Firestore.firestore()
let postsRef = db.collection("posts")
postsRef.addSnapshotListener { (querySnapshot, error) in
guard let snapshot = querySnapshot else {
print("Error fetching snapshots: \(error!)")
return
}
snapshot.documentChanges.forEach { diff in
if (diff.type == .added){
let data = diff.document.data()
let Name = data["username"] as! String
let text = data["description"] as! String
let likes = data["likes"] as! Int
let typ = data["postType"] as! Int
let pfp = data["profileImage"] as! String
let uid = data["uid"] as! String
let pic = data["picture"]
let time = data["time"] as! String
if typ == 0{ // Text post
let dasDing = TextPost(numberOfComments: 0, username: Name, timestampName: time, userImageName: pfp, textName: text)
self.texttt.append(dasDing)
}
}
}
DispatchQueue.main.async {
tableView.reloadData()
}
}
}
This question already has answers here:
Searchbar filtering issue
(3 answers)
Closed 3 years ago.
I'm trying to be able to search my Firebase data using a UISearchBar in my app & I am stuck. I am successfully receiving data from Firebase in a table view. I have a memories-writing app that the user can create memories (that are shown in a tableview from the firebase). memories has a title, description, a pic and a date and I want it to be able to search memories by the title.
I have a code here that doesn't work for some reason... il'l be glad if you could help me find out what's wrong in the code or find a replacement for this code :)
MemoryTitles class:
class MemoryTitles {
var title : String
init(withTitle: String) {
self.title = withTitle
}
}
MemoryViewController:
class MemoryViewController: UIViewController,UITableViewDelegate,UITableViewDataSource
// the filtered memories array for the search bar
var memoriesTitlesArr: [String] = []
var filteredDataa: [String] = []
// connections from storyboard to the code
#IBOutlet weak var tbl: UITableView!
#IBOutlet weak var searchBar: UISearchBar!
// an array of memories
var memories : [Memory] = []
var ref = Database.database().reference()
let sref = Storage.storage().reference()
var lastIndex : Int = 0
var strMode : String = ""
// TableView functions
// Return the number of rows in section
// section - an index number identifying a section in tableView.
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if searching {
return filteredDataa.count
} else {
return memories.count
}
// return memories.count
}
// Return Cell for row function : an object inheriting from UITableViewCell
// indexPath - an index path locating a row in tableView.
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "iden")
if searching {
cell?.textLabel?.text = filteredDataa[indexPath.row]
} else {
var cell : UITableViewCell? = tableView.dequeueReusableCell(withIdentifier: "iden", for: indexPath)
if cell == nil
{
cell = UITableViewCell(style: UITableViewCell.CellStyle.default, reuseIdentifier: "iden")
}
let temp = memories[indexPath.row]
cell?.textLabel?.text = temp.title
cell?.imageView?.image = temp.image
return cell!
}
return cell!
}
// Can edit row : asks the data source to verify that the given row is editable.
// indexPath - an index path locating a row in tableView.
func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
return true // true if the row indicated by indexPath is editable; otherwise, false.
}
// Asks the data source to commit the insertion or deletion of a specified row.
// indexPath - an index path locating a row in tableView.
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == .delete // editingStyle - the cell editing style corresponding to a insertion or deletion requested for the row specified by indexPath.
{
let temp = self.memories[indexPath.row]
self.memories.remove(at: indexPath.row)
self.ref.child("MEmories/\(temp.key)").removeValue()
tableView.deleteRows(at: [indexPath as IndexPath], with: .fade)
}
}
override func viewDidLoad() {
super.viewDidLoad()
ref = Database.database().reference()
let rightButton = UIBarButtonItem(barButtonSystemItem: .add, target: self, action: #selector(MemoryViewController.barButtonItemClicked(_:)))
self.navigationItem.setRightBarButton(rightButton, animated: true)
// Do any additional setup after loading the view.
self.loadMemories()
self.tbl.delegate = self
self.tbl.dataSource = self
}
// click on bar-Button function
#objc func barButtonItemClicked(_ sender:UIBarButtonItem)
{
print("+ clicked") // writes "+ clicked"
let addMemoryViewController = self.storyboard?.instantiateViewController(withIdentifier: "AddMemoryViewController") as! AddMemoryViewController
self.strMode = "newMemory"
self.navigationController?.pushViewController(addMemoryViewController, animated: true)
}
// Reading from NSUserDefault (A class that provides simple storage of different data types solution.)
func readFromNSUserDefault()-> Memory?
{
let d : UserDefaults = UserDefaults.standard
let strTitle = d.object(forKey: "title") as? String
let strBody = d.object(forKey: "body") as? String
let strImageRef = d.object(forKey: "imageRef") as? String
let uid = d.object(forKey: "uid") as? String
let imageData = d.object(forKey: "imageData") as? Data
let key = d.object(forKey: "key") as? String
let date = d.object(forKey: "date") as? NSNumber
let m = Memory(title: strTitle!, body: strBody!, key: key!, uid: uid!, imageRef: strImageRef!, date: date!) // A variable from type memory
m.image = UIImage(data: imageData!)
m.key = key!
return m
}
override func viewDidAppear(_ animated: Bool) {
let d = UserDefaults.standard
let newMemory = readFromNSUserDefault()
let userAdded = d.bool(forKey: "userAdded") //key new user = true
let userEdited = d.bool(forKey: "userEdited")//key user edited = true
if self.strMode == "newMemory" && userAdded
{
self.memories.append(newMemory!)
self.tbl.reloadData()
}
else if self.strMode == "edit" && userEdited
{
memories[lastIndex] = newMemory!
self.tbl.reloadData()
}
d.set(false, forKey: "userAdded")
d.set(false, forKey: "userEdited")
d.synchronize()
self.strMode = " "
}
// loading the memories from the Database
func loadMemories()
{
let UID = Auth.auth().currentUser!.uid
self.ref.child("MEmories").queryOrdered(byChild: "uid").queryEqual(toValue: UID).observeSingleEvent(of: .value, with: {
snapShot in
if let dict = snapShot.value as? NSDictionary
{
for d in (dict as? Dictionary<String,AnyObject>)!
{
let title = d.value["title"] as?String
let body = d.value["body"] as? String
let uid = d.value["uid"] as? String
let imageRef = d.value["imageRef"] as? String
let date = d.value["date"] as? NSNumber
let m = Memory(title: title!, body: body!, uid: uid!,imageRef:imageRef!, date: date!)
m.key = d.key
let tempImageRef = self.sref.child(m.imageRef)
tempImageRef.getData(maxSize: 500*1024*1024, completion: {(data,error) in
if error == nil
{
if let imageData = data
{
m.image = UIImage(data: imageData)
self.memories.append(m)
self.tbl.reloadData()
}
}
})
self.memoriesTitlesArr.append(title!)
}
}//end of if
})
}
// Notifies the view controller that a segue is about to be performed.
// segue - The segue object containing information about the view controllers involved in the segue.
// senderThe object that initiated the segue.
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let identifier = segue.identifier
{
if identifier == "goToEdit"
{
let indexPath = self.tbl.indexPathForSelectedRow
let addMemoryViewController = segue.destination as! AddMemoryViewController
self.strMode = "edit"
self.lastIndex = (indexPath?.row)!
addMemoryViewController.mode = self.strMode
addMemoryViewController.current = memories[(indexPath?.row)!]
}
}
}
var searching = false
}
extension MemoryViewController: UISearchBarDelegate {
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
filteredDataa = memoriesTitlesArr.filter({ $0.prefix(searchText.count)==searchText.lowercased()})
searching = true
tbl.reloadData()
}
func searchBarCancelButtonClicked(_ searchBar: UISearchBar) {
searching = false
searchBar.text = ""
tbl.reloadData()
}
}
Here is how you can get that working.
1. First of all, there is no need for searching to maintain the state of searching and not searching.
2. Secondly, use filteredData as the dataSource for tableView instead of memories. filteredData will initially contain all the objects from memories, i.e.
var memories : [Memory] = []
lazy var filteredData = self.memories
The UITableViewDataSource methods will be like,
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.filteredData.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if let cell = tableView.dequeueReusableCell(withIdentifier: "iden") {
cell.textLabel?.text = self.filteredData[indexPath.row].title
return cell
}
return UITableViewCell()
}
Now, while searching update the filteredData with filtered memories using the relevant condition, i.e.
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
self.filteredData = self.memories.filter({ $0.title.hasPrefix(searchText) })
//change the condition as per your requirement......
self.tbl.reloadData()
}
func searchBarCancelButtonClicked(_ searchBar: UISearchBar) {
searchBar.text = nil
self.filteredData = self.memories
self.tbl.reloadData()
}
When cancelled, refill the filteredData with the whole memories data.
am trying to use UISearchbar with my firebase database but i don't know if my code is rghit or not becuase it's crash everytime i run it and this's my code
var hotelList = [hotelsModel]()
var hotelsArray : [NSDictionary] = []
var filterHotels : [NSDictionary] = []
var databaseRef = Database.database().reference()
databaseRef.child("Hotels").queryOrdered(byChild: "name").observe(.childAdded, with: { (snapshot) in
self.hotelsArray.append(snapshot.value as! NSDictionary)
self.tableView.insertRows(at: [IndexPath(row: self.hotelsArray.count-1, section: 0)], with: UITableView.RowAnimation.automatic)
List item
}) { (error) in
print(error.localizedDescription)
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
//creating a cell using the custom class
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! hotelsTableViewCell
let hotelSearch : NSDictionary?
//the artist object
var hotel: hotelsModel
//getting the artist of selected position
//hotel = hotelList[indexPath.row]
if searchController.isActive && searchController.searchBar.text != "" {
hotelSearch = filterHotels[indexPath.row] as! NSDictionary
} else {
//getting the artist of selected position
hotel = hotelList[indexPath.row]
}
//getting the artist of selected position
hotel = hotelList[indexPath.row]
//adding values to labels
cell.lblName.text = hotel.name
cell.lblLocation.text = hotel.location
cell.appSuggest.text = hotel.appSuggest
cell.price.text = hotel.price
cell.canceletion.text = hotel.cancelation
cell.paymentNeeded.text = hotel.paymentNeeded
if let imgUrl = hotel.img{
let url = URL(string: imgUrl)
cell.img.kf.setImage(with: url)
cell.img.clipsToBounds = true
cell.img.layer.cornerRadius = 10
cell.img.layer.shadowColor = UIColor.black.cgColor
cell.img.layer.shadowOpacity = 1.8
cell.img.layer.shadowOffset = CGSize(width: 5, height: 0)
}
return cell
}
func updateSearchResults(for searchController: UISearchController) {
//update the searchbar result
//filterHotels(serachText:searchController.searchBar.text!)
filterHotels.removeAll()
filterHotels = hotelsArray.filter({ (text) -> Bool in
let tmp: NSString = (text as? NSString ?? nil) ?? ""
let range = tmp.range(of: searchController.searchBar.text!, options: NSString.CompareOptions.caseInsensitive)
return range.location != NSNotFound
})
self.tableView.reloadData()
}
it's crashed in this line
self.hotelsArray.append(snapshot.value as! NSDictionary)
How can I solve this?
Thank You
I would like to show my saved data in core data on a table view controller, the data is saved properly and prints out the details on the console but the data is noot showing up on the tableview cell, kindly please help
var charData = [SavedCharacters]()
let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
var name = String()
var house = String()
var ancestry = String()
var getImage = UIImage()
override func viewDidLoad() {
super.viewDidLoad()
getData()
}
func getData(){
let request = NSFetchRequest<NSFetchRequestResult>(entityName: "SavedCharacters")
request.returnsObjectsAsFaults = false
do{
let result = try? context.fetch(request)
for data in result as! [NSManagedObject]
{
name = data.value(forKey: "name") as! String
print(data.value(forKey: "name")as! String)
}
}
tableView.reloadData()
}
override func numberOfSections(in tableView: UITableView) -> Int {
// #warning Incomplete implementation, return the number of sections
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return charData.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "dataCell", for: indexPath) as! SavedDataTableViewCell
cell.nameLabel.text = charData[indexPath.row].name!
cell.house = charData[indexPath.row].house!
cell.ancestry = charData[indexPath.row].ancestry!
// displaying image in table view cell
if let imageURL = URL(string: self.charData[indexPath.row].image!) {
DispatchQueue.global().async {
let data = try? Data(contentsOf: imageURL)
if let data = data {
let image = UIImage(data: data)
DispatchQueue.main.async {
cell.charImageView.image = image
}
}
}
}
return cell
}
Definitely you've forgotten to init charData in getData() method
var charData: [CharData]
func getData(){
let request = NSFetchRequest<NSFetchRequestResult>(entityName: "SavedCharacters")
request.returnsObjectsAsFaults = false
====> charData = []
do{
let result = try? context.fetch(request)
for data in result as! [CharData]
{
name = data.value(forKey: "name") as! String
print(data.value(forKey: "name")as! String)
===> charData.append(data)
}
}
tableView.reloadData()
}
I am attempting to reloadData() after fetching data in an async operation from Firebase. I am having difficulty finding the appropriate location to do the reloadData() as at different location, it either refreshes one section of the tableView and not the other, or it does not refresh at all, or worse, the refresh jumbles up the dataset.
Here is my code so far, and a description of the outcome when I reloadData() at that particular location:
func getData() {
DispatchQueue.main.async {
self.titleView.setTitle(viewController: self, animate: true, title: "Updating...")
}
ref.child("conversations").child(userUID).observeSingleEvent(of: .value) { (snapshot) in
for snap in snapshot.children {
let snapDatasnapshot = snap as! DataSnapshot
let snapValues = snapDatasnapshot.value as! [String: AnyObject]
let recipientUID = snapDatasnapshot.key
for (key, value) in snapValues {
let conversationStartTime = value["conversationStartTime"] as! Double
if calculateMinutesLeft(conversationStartTime) >= 0 {
let messagesDatasnapshot = snapDatasnapshot.childSnapshot(forPath: shoutoutID).childSnapshot(forPath: "messages")
let messagesArray = messagesDatasnapshot.value as! [String: AnyObject]
self.startTimeDictionary[shoutoutID] = conversation
for message in messagesArray {
let messageID = message.key
self.ref.child("messages").child(messageID).observeSingleEvent(of: .value, with: { (messagesSnapshot) in
let dictionary = messagesSnapshot.value as! [String: AnyObject]
let timestamp = dictionary["timestamp"] as! Double
let readReceipt = dictionary["readReceipt"] as! Bool
if let messageText = dictionary["message"] {
let message = messageText as! String
let m = Message(fromUserUID: self.userUID, message: message, timestamp: timestamp, recipientUserUID: recipientUID, imageUrl: nil, readReceipt: readReceipt)
self.messagesDictionary[conversation] = m
self.messages = Array(self.messagesDictionary.values)
}
//Location 1
DispatchQueue.main.async {
self.tableView.reloadData()
self.titleView.setTitle(viewController: self, animate: false, title: "Chats")
}
})
}
} else {
//Expired Convos
self.expiredConversations.append(conversation)
//Location 2
DispatchQueue.main.async {
self.tableView.reloadData()
self.titleView.setTitle(viewController: self, animate: false, title: "Chats")
}
}
}
}
if self.messages.isEmpty && self.expiredConversations.isEmpty {
self.titleView.setTitle(viewController: self, animate: false, title: "Chats")
}
//Location 3
DispatchQueue.main.async {
self.tableView.reloadData()
self.titleView.setTitle(viewController: self, animate: false, title: "Chats")
}
}
//Location 4
DispatchQueue.main.async {
self.tableView.reloadData()
self.titleView.setTitle(viewController: self, animate: false, title: "Chats")
}
}
The messages will be displayed in section 0 of the tableView while expiredConversations will be displayed in section 1 of the tableView.
My current implementation is at location 1 and 2. Doing so correctly reloads both sections of the table but will tend to jumble the data up when refreshed multiple times, or when tableView size gets too large. Otherwise:
At location 1 only, will refresh just section 0
At location 2 only, will refresh just section 1
At location 3 and 4, will refresh all sections, but give empty messages and expiredConversations
Any advice where is the best or ideal location to reloadData()? Or could my implementation be wrong totally?
EDIT: tableViewDelegate and tableViewDatasource
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
switch section {
case 0:
if messages.isEmpty {
return 1
} else {
return messages.count
}
case 1:
return expiredConversations.count
default:
return 0
}
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
switch indexPath.section {
case 0:
if messages.isEmpty {
let noConversationsCell = tableView.dequeueReusableCell(withIdentifier: "noConversationsCell", for: indexPath) as! NoActiveConversationsTableViewCell
noConversationsCell.isUserInteractionEnabled = false
return noConversationsCell
} else {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! ChatLogTableViewCell
let message = messages[indexPath.row]
let conversation = conversations[indexPath.row]
//All the data model thing to populate the cells
return cell
}
case 1:
let expiredConversationsCell = tableView.dequeueReusableCell(withIdentifier: "expiredConversationsCell", for: indexPath) as! ExpiredConversationsTableViewCell
let conversation = expiredConversations[indexPath.row]
//All the data model thing to populate the cells
return expiredConversationsCell
default:
return UITableViewCell()
}
}