如何在我的 searchcontroller 中使用 queryStartingAtValue 来搜索用户?

2024-01-22

我之前曾问过一个关于以最具成本效益的方式搜索用户的问题(无需加载整个数据库中的每个用户)。

问题之前我的代码是

class FollowUsersTableViewController: UIViewController{

@IBOutlet var tableView: UITableView!

private var viewIsHiddenObserver: NSKeyValueObservation?
let searchController = UISearchController(searchResultsController: nil)
var usersArray = [UserModel]()
var filteredUsers = [UserModel]()
var loggedInUser: User?
//
var databaseRef = Database.database().reference()
//usikker på den koden over

override func viewDidLoad() {
    super.viewDidLoad()
    //large title
    self.title = "Discover"
    if #available(iOS 11.0, *) {
        self.navigationController?.navigationBar.prefersLargeTitles = true
    } else {
        // Fallback on earlier versions
    }

    self.tableView?.delegate = self
    self.tableView?.dataSource = self
    searchController.searchResultsUpdater = self
    searchController.dimsBackgroundDuringPresentation = false
    self.searchController.delegate = self;

    definesPresentationContext = true
    tableView.tableHeaderView = searchController.searchBar

    self.loadProfileData()
}

func loadProfileData() {
    databaseRef.child("profile").queryOrdered(byChild: "username").observe(.childAdded, with: { (snapshot) in
        print(snapshot)
        let userObj =  Mapper<UserModel>().map(JSONObject: snapshot.value!)
        userObj?.uid = snapshot.key

        guard snapshot.key != self.loggedInUser?.uid else { return }

        self.usersArray.append(userObj!)
    })
}

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    let dest = segue.destination as! UserProfileViewController
    let obj = sender as! UserModel
    let dict = ["uid": obj.uid!, "username": obj.username!, "photoURL": obj.photoURL, "bio": obj.bio]
    dest.selectedUser = dict as [String : Any]
}

  }

   // MARK: - tableview methods
   extension FollowUsersTableViewController: UITableViewDataSource, 
  UITableViewDelegate {

func tableView(_ tableView: UITableView, numberOfRowsInSection 
 section: Int) -> Int {
    return searchController.searchBar.text!.count >= 2 ? 
 filteredUsers.count : 0
  }

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! FollowTableViewCell

    let user = filteredUsers[indexPath.row]

    cell.title?.text = user.username
    if let url = URL(string: user.photoURL ?? "") {
        cell.userImage?.sd_setImage(with: url, placeholderImage: 
     #imageLiteral(resourceName: "user_male"), options: 
  .progressiveDownload, completed: nil)
        cell.userImage.sd_setIndicatorStyle(.gray)
        cell.userImage.sd_showActivityIndicatorView()
    }

    return cell
}

 func tableView(_ tableView: UITableView, heightForRowAt indexPath: 
   IndexPath) -> CGFloat {
    return 50
}

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: 
 IndexPath) {
    self.performSegue(withIdentifier: "user", sender: self.filteredUsers[indexPath.row])
}

 }

 // MARK: - search methods
 extension FollowUsersTableViewController:UISearchResultsUpdating, 
   UISearchControllerDelegate {

func updateSearchResults(for searchController: UISearchController) {
    searchController.searchResultsController?.view.isHidden = false
    filterContent(searchText: self.searchController.searchBar.text!)
    self.tableView.reloadData()
}

func filterContent(searchText:String){
    if searchText.count >= 2{
        self.filteredUsers = self.usersArray.filter{ user in
            return(user.username!.lowercased().contains(searchText.lowercased()))
        }
    }
   }
  }

但后来用户“maxwell”回复我并建议使用 queryStartingAtValue,如下所示:

func searchQueryUsers(text: String, completion: @escaping (_ userNames: [String]) -> Void) {

    var userNames: [String] = []

    databaseRef.child("profile").queryOrdered(byChild: "username").queryStarting(atValue: text).observeSingleEvent(of: .value, with: { snapshot in

        for item in snapshot.children {

            guard let item = item as? DataSnapshot else {
                break
            }

            //"name" is a key for name in FirebaseDatabese model
            if let dict = item.value as? [String: Any], let name = dict["name"] as? String {
                userNames.append(name)
            }
        }

        completion(userNames)
    })
}

我怎样才能用我现有的代码来实现这个Mapper<UserModel>().map(JSONObject)?我尝试实现他的代码,但找不到真正有效地做到这一点的方法,而且我似乎无法联系到麦克斯韦,所以有人可以帮我解决这个问题吗?

我应该使用 searchController.searchBar.text 作为 maxwells 代码中的“文本”吗?

Thanks,

为杰伊更新:

 class FollowUsersTableViewController: UIViewController, 
 UISearchBarDelegate {

@IBOutlet var tableView: UITableView!

private var viewIsHiddenObserver: NSKeyValueObservation?
let searchController = UISearchController(searchResultsController: nil)
var usersArray = [UserModel]()
var filteredUsers = [UserModel]()
var loggedInUser: User?
//
var databaseRef = Database.database().reference()
//usikker på den koden over

override func viewDidLoad() {
    super.viewDidLoad()
    //large title
    self.title = "Discover"
    if #available(iOS 11.0, *) {
        self.navigationController?.navigationBar.prefersLargeTitles = true
    } else {
        // Fallback on earlier versions
    }

    self.tableView?.delegate = self
    self.tableView?.dataSource = self
    searchController.searchResultsUpdater = self
    searchController.dimsBackgroundDuringPresentation = false
    self.searchController.delegate = self;



    definesPresentationContext = true
    tableView.tableHeaderView = searchController.searchBar

    //self.loadProfileData()

   //self.searchBar(searchController.searchBar, textDidChange: searchController.searchBar.text)







}

func searchUsers(text: String) {
    if text.count > 0 {
        self.usersArray = [] //clear the array each time
        let endingText = text + "\u{f8ff}"
        databaseRef.child("profile").queryOrdered(byChild: "username")
            .queryStarting(atValue: text)
            .queryEnding(atValue: endingText)
            .observeSingleEvent(of: .value, with: { snapshot in

                for child in snapshot.children {
                    let childSnap = child as! DataSnapshot
                    let userObj =  Mapper<UserModel>().map(JSONObject: childSnap.value!)
                    userObj?.uid = childSnap.key
                    if childSnap.key != self.loggedInUser?.uid { //ignore this user
                        self.usersArray.append(userObj!)
                    }
                }
                self.tableView.reloadData()
            })
    }
} //may need an else statement here to clear the array when there is no text


override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    let dest = segue.destination as! UserProfileViewController
    let obj = sender as! UserModel
    let dict = ["uid": obj.uid!, "username": obj.username!, "photoURL": obj.photoURL, "bio": obj.bio]
    dest.selectedUser = dict as [String : Any]
}

func searchBar(_ searchBar: UISearchBar,
               textDidChange searchText: String) {

    self.searchUsers(text: searchText)
}




 }

问题中的代码几乎是正确的,只需要对其进行调整以确保枚举变量是快照,然后将其与 Mapper 一起使用。

当用户输入用户名时,每次按键都会递归调用该用户名;因此,如果他们在 Leroy 中输入,则首先输入 L,此代码将检索用户名值以“L”开头的所有节点。然后用户输入“e”使其成为“Le”等等。

func searchUsers(text: String) {
    if text.count > 0 {
       self.usersArray = [] //clear the array each time
       let endingText = text + "\u{f8ff}"
       databaseRef.child("profile").queryOrdered(byChild: "username")
                                   .queryStarting(atValue: text)
                                   .queryEnding(atValue: endingText)
                                   .observeSingleEvent(of: .value, with: { snapshot in

           for child in snapshot.children {
               let childSnap = child as! DataSnapshot
               let userObj =  Mapper<UserModel>().map(JSONObject: childSnap.value!)
               userObj?.uid = childSnap.key
               if childSnap.key != self.loggedInUser?.uid { //ignore this user
                  self.usersArray.append(userObj!)
               }
           }
           self.tableView.reloadData()
       })
    }
  } //may need an else statement here to clear the array when there is no text

EDIT:

OP 请求通过 searchBar 和 if 语句处理搜索的代码,以防止在没有文本的情况下进行搜索。这是调用上面的 searchUsers 函数的委托方法

func searchBar(_ searchBar: UISearchBar,
               textDidChange searchText: String) {

    self.searchUsers(text: searchText)
}

EDIT:

OP 想看看我的 viewDidLoad 函数,尽管它并不令人兴奋,所以就在这里。

class ViewController: UIViewController, UISearchBarDelegate 
    override func viewDidLoad() {
       super.viewDidLoad()

       // Do any additional setup after loading the view.
    }
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在我的 searchcontroller 中使用 queryStartingAtValue 来搜索用户? 的相关文章

随机推荐

  • 如何使用 AWS IoT 向 Web 浏览器发送消息/从 Web 浏览器接收消息

    我们正在尝试使用 Amazon Web Services 物联网 AWS IoT 从 Web 浏览器发送消息 向 Web 浏览器发送消息 例如 鉴于 AWS IoT 支持 JavaScript 我们expect这是possible 我们已经
  • Github 未检测到新文件夹

    我正在使用连接到我的远程 bitbuckket git 的 Github Windows 客户端 我最近开始在 mobile 中构建应用程序的移动版本 我一直在 localhost WEBSITE NAME 中工作 但现在在 localho
  • 可以将部分域名作为我的路由规则中的参数吗?

    我想要一个路由规则接受我的部分域名作为参数 例如 name mydomain com photos id 这可能吗 我在使用 asp net mvc 时遇到了类似的问题 但使用整个域而不仅仅是子域 我们使用的是自定义路由约束来确定要转到哪个
  • 使用 json (body: raw) POST 数据时总是失败

    我在向服务器发送数据时遇到问题 我正在使用 React Native 和 axios 版本 0 16 2 let input longitude 6 3922782 latitude 106 8268856 content uget uge
  • Jquery Isotope 和 Twitter Bootstrap 网格

    我正在尝试将 jQuery Isotope 与我的 Twitter Bootstrap 网格一起实现 但我陷入了困境 我有一个常用的列引导标记 我有三行 row fluid 每行内有三列 span4 现在 当我在上述列上调用 Isotope
  • 使用弹出界面设计离子选择

    我正在创建一个带有弹出界面的离子选择元素 我想设计离子选择选项的样式 以便它们跨越屏幕的宽度 但我尝试过的任何方法都不起作用
  • 长时间运行的实体框架事务

    当用户打开某个实体的编辑表单时 我想锁定该实体并让她进行任何更改 在编辑过程中 她需要确保没有其他人对其进行任何编辑操作 如何锁定实体框架 C 4 数据库 MS SQL Server 2008 中的实体 提前非常感谢 坏主意 特别是如果您有
  • Actionmailer - Sparkpost 模板和多语言

    这是我第一次在 Rails 项目中设置邮件 我被告知要使用 SparkPost 并为多个操作的不同语言创建模板 为了简单起见 我们假设一封 user signed up user 邮件 目前我的设置有效 安装的宝石 sparkpost ma
  • 在服务器 JRE 与 JRE 中运行应用程序的主要区别是什么? [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我在oracle网站上看到有两种类型的jre下载 在服务器 JRE 与 JRE 中运行我的应用程序有什么区别 选择一种运行时环境而不是另一
  • 自定义 PowerShell 提示[关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 带有“#”的意图过滤器路径前缀不起作用

    我正在尝试设置一个意图过滤器 以便在用户单击以下 URI 时启动我的活动 example com pathA pathB pathC someGUID 所以我将以下 XML 添加到清单文件中
  • 从 UICollectionView 索引路径获取模型

    我在用着RxSwift将模型数组绑定到集合视图 如何从给定的indexPath获取模型对象 我正在像这样进行绑定 vm bikeIssueCatagories drive self collectionView rx items cellI
  • Docker 创建了两个桥来破坏我的互联网访问

    我面临一个非常奇怪的问题 这是我的配置 docker 17 ce ubuntu 16 04 我在两个不同的地方与不同的互联网提供商工作 首先 一切工作正常 我可以开箱即用地运行 docker 并毫无问题地访问互联网 但第二 当 docker
  • 在没有输出文件的情况下调用 aws lambda

    我正在尝试使用 CLI 在 AWS 上调用 lambda aws lambda invoke function name GetErrorLambda payload body Id 321 123 output 我想知道是否有办法在 cl
  • 链接服务器和同义词之间的区别?

    t sql链接服务器和同义词有区别吗 如果是的话 它们是什么 在什么情况下我会选择其中之一 您使用链接服务器连接到不同服务器上的数据库 您使用同义词来指定要在 SQL 中访问的对象 例如表 它就像别名 欲了解更多信息 请参阅here htt
  • String.Format 在字符串内存储双引号[重复]

    这个问题在这里已经有答案了 我想表示以下字符串 aaaa 23 something inside double quotes 99 8 7 我想用这个来做到这一点String Format StringBuilder AppendLine
  • 在 Spring Security 中使用自定义异常

    我创建了一个自定义AuthenticationProvider执行自定义安全检查 我还创建了继承自的自定义异常AccountStatusException通知用户状态问题 例如用户在特定时间段内未验证其帐户 我的UserDetails也是一
  • 如何测量 React 16 中浪费的渲染?

    我之前用过反应插件性能 https reactjs org docs perf html printwasted包来测量各种东西 例如浪费的渲染通过Perf printWasted 不幸的是 这个包在 React 16 中被淘汰 取而代之的
  • screen.width/height 给出有关屏幕分辨率的错误信息

    我的屏幕分辨率为 1200 x 800 但此脚本给我的分辨率为 1429 x 893 为什么它不起作用 附注在其他网站上这段代码screen width screen height但是当在本地主机上运行它时 它会给出错误的信息 From M
  • 如何在我的 searchcontroller 中使用 queryStartingAtValue 来搜索用户?

    我之前曾问过一个关于以最具成本效益的方式搜索用户的问题 无需加载整个数据库中的每个用户 问题之前我的代码是 class FollowUsersTableViewController UIViewController IBOutlet var