您如何使用SearchBar在tableview中的Firebase数据中进行搜索?

问题描述

我已经建立了一个表格视图,该表格视图从firebase实时数据库中检索数据,并将此数据存储在以下格式的数组(“帖子”)中:

(姓名:无,contactEmail:可选(“ 35345345235”),contactPhoneNum:可选(“ [email protected]”),年龄:可选(“ 25”),性别:无,lastSeen:无, profileDescription:无)

我想实现一个搜索栏来过滤帖子的名称值,并返回在表视图中包含搜索到的名称的帖子,并且不确定如何执行此操作。

这是我的代码

import UIKit
import Firebase
import FirebaseDatabase
import SwiftKeychainWrapper
import FirebaseAuth

class FeedVC: UITableViewController,UISearchBarDelegate{
    
    @IBOutlet weak var searchBar: UISearchBar!
    
    var currentUserImageUrl: String!
    var posts = [postStruct]()
    var selectedPost: Post!
    var filteredPosts = [postStruct]()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        getUsersData()
        getPosts()
        searchBar.delegate = self
        // Do any additional setup after loading the view.
   //     tableView.register(PostCell.self,forCellReuseIdentifier: "PostCell")
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // dispose of any resources that can be recreated.
    }
    
    
    func getUsersData(){

        guard let userID = Auth.auth().currentUser?.uid else { return }
        Database.database().reference().child("users").child(userID).observeSingleEvent(of: .value) { (snapshot) in
            if let postDict = snapshot.value as? [String : AnyObject] {
                self.tableView.reloadData()
            }
        }
    }
    
    struct postStruct {
        let name : String!
        let contactEmail : String!
        let contactPhoneNum : String!
        let age : String!
        let gender : String!
        let lastSeen : String!
        let profileDescription : String!
    }
    
    func getPosts() {
        let databaseRef = Database.database().reference()
        databaseRef.child("firstName").queryOrderedByKey().observe( .childAdded,with: {
                    snapshot in
                    let name = (snapshot.value as? NSDictionary)!["name"] as? String
                    let contactEmail = (snapshot.value as? NSDictionary
                    )!["contactEmail"] as? String
                    let contactPhoneNum = (snapshot.value as? NSDictionary
                    )!["contactPhoneNum"] as? String
                    let age = (snapshot.value as? NSDictionary
                    )!["age"] as? String
                    let gender = (snapshot.value as? NSDictionary
                    )!["gender"] as? String
                    let lastSeen = (snapshot.value as? NSDictionary
                    )!["lastSeen"] as? String
                    let profileDescription = (snapshot.value as? NSDictionary
                    )!["profileDescription"] as? String
            self.posts.append(postStruct(name: name,contactEmail:contactEmail,contactPhoneNum:contactPhoneNum,age:age,gender:gender,lastSeen:lastSeen,profileDescription:profileDescription))
            dispatchQueue.main.async {
                        self.tableView.reloadData()
                    }
                })
    }
    
    override func numberOfSections(in tableView: UITableView) -> Int {
        return 1
    }
    
    override func tableView(_ tableView: UITableView,numberOfRowsInSection section: Int) -> Int {
        print("posts count = ",filteredPosts.count)
        return filteredPosts.count

   }
    
    override func tableView(_ tableView: UITableView,heightForRowAt indexPath: IndexPath) -> CGFloat {
      //  tableView.dequeueReusableCell(withIdentifier: "PostCell")!.frame.size.height
        return 230
    }
   override func tableView(_ tableView: UITableView,cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        guard let cell = tableView.dequeueReusableCell(withIdentifier: "PostCell") as? PostCell else { return UITableViewCell() }
    cell.nameLabel?.text = filteredPosts[indexPath.row].name
        cell.contactEmailLabel?.text = filteredPosts[indexPath.row].contactEmail
        cell.contactPhoneNumLabel?.text = filteredPosts[indexPath.row].contactPhoneNum
        cell.ageLabel?.text = filteredPosts[indexPath.row].age
        cell.genderLabel?.text = filteredPosts[indexPath.row].gender
        cell.lastSeenLabel?.text = filteredPosts[indexPath.row].lastSeen
        cell.profileDescriptionLabel?.text = filteredPosts[indexPath.row].profileDescription
        print(filteredPosts)
        return cell
    }
    
    func searchBar(_ searchBar: UISearchBar,textDidChange searchText: String) {
          filteredPosts = posts.filter { $0.name?.lowercased().contains(searchText.lowercased()) == true }
}


}

解决方法

posts上循环将提供类型Post而不是String的元素。解决方法:

func searchBar(_ searchBar: UISearchBar,textDidChange searchText: String) {
    filteredPosts = []
    for post in posts {
        if post.name?.lowercased().contains(searchText.lowercased()) == true {
            filteredPosts.append(post)
        }
    }
}

或者只是使用受{@Jay评论启发的filter之类的高阶方法。

func searchBar(_ searchBar: UISearchBar,textDidChange searchText: String) {
    filteredPosts = posts.filter { $0.name?.lowercased().contains(searchText.lowercased()) == true }
}