Smart-Search for Parse Usernames in Swift Not Working

Smart-search for Parse Usernames in Swift not working

You will want to implement the UISearchResultsUpdating protocol to achieve this. It uses a UISearchController (introduced in iOS 8) which has to be added programmatically instead of through the storyboard, but don't worry, it's pretty straight-forward.

This should get the job done for you

Cheers,
Russell

class YourTableViewController: UITableViewController, UISearchBarDelegate, UISearchResultsUpdating {
var searchUsers: [PFUser] = [PFUser]()
var userSearchController = UISearchController()
var searchActive: Bool = false

// MARK: - Lifecycle

override func viewDidLoad() {
super.viewDidLoad()

self.userSearchController = UISearchController(searchResultsController: nil)
self.userSearchController.dimsBackgroundDuringPresentation = true

// This is used for dynamic search results updating while the user types
// Requires UISearchResultsUpdating delegate
self.userSearchController.searchResultsUpdater = self

// Configure the search controller's search bar
self.userSearchController.searchBar.placeholder = "Search for a user"
self.userSearchController.searchBar.sizeToFit()
self.userSearchController.searchBar.delegate = self
self.definesPresentationContext = true

// Set the search controller to the header of the table
self.tableView.tableHeaderView = self.userSearchController.searchBar
}

// MARK: - Parse Backend methods

func loadSearchUsers(searchString: String) {
var query = PFUser.query()

// Filter by search string
query.whereKey("username", containsString: searchString)

self.searchActive = true
query.findObjectsInBackgroundWithBlock { (objects: [AnyObject]?, error: NSError?) -> Void in

if (error == nil) {
self.searchUsers.removeAll(keepCapacity: false)
self.searchUsers += objects as! [PFUser]
self.tableView.reloadData()
} else {
// Log details of the failure
println("search query error: \(error) \(error!.userInfo!)")
}
self.searchActive = false
}
}

// MARK: - Search Bar Delegate Methods

func searchBarSearchButtonClicked(searchBar: UISearchBar) {

// Force search if user pushes button
let searchString: String = searchBar.text.lowercaseString
if (searchString != "") {
loadSearchUsers(searchString)
}
}

func searchBarCancelButtonClicked(searchBar: UISearchBar) {

// Clear any search criteria
searchBar.text = ""

// Force reload of table data from normal data source
}

// MARK: - UISearchResultsUpdating Methods

// This function is used along with UISearchResultsUpdating for dynamic search results processing
// Called anytime the search bar text is changed
func updateSearchResultsForSearchController(searchController: UISearchController) {

let searchString: String = searchController.searchBar.text.lowercaseString
if (searchString != "" && !self.searchActive) {
loadSearchUsers(searchString)
}
}

// MARK: - Table view data source

override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}

override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if (self.userSearchController.active) {
return self.searchUsers.count
} else {
// return whatever your normal data source is
}
}

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell = tableView.dequeueReusableCellWithIdentifier("userCell") as! UserCell

if (self.userSearchController.active && self.searchUsers.count > indexPath.row) {
// bind data to the search results cell
} else {
// bind data from your normal data source
}

return cell
}

// MARK: - UITableViewDelegate

override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
tableView.deselectRowAtIndexPath(indexPath, animated: true)

if (self.userSearchController.active && self.searchUsers.count > 0) {
// Segue or whatever you want
} else {
// normal data source selection
}
}
}

Swift - Problems following & unfollowing users when searched via UISearchController [Parse]

You need to check if the UISearchController is active inside of didSelectRowAtIndexPath. Right now you are only selecting from the users array instead of from the searchResults array.

I also highly recommend refactoring your code away from using objectIds and use pointers. It is much easier to query against and work with pointers rather than directly accessing their objectIds.

Here's a link to another question that I've previously answered where I give a complete example of using a UISearchController to search by usernames in Parse.. Hope this helps!

How to allow users to search based on two criteria

Try to edit your code like this:

func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) 
{
if searchText.isEmpty || searchText == " " {
inSearchMode = false
} else {
inSearchMode = true
filteredUsers = users.filter({ (user) -> Bool in
return (user.name?.contains(searchText) ?? true) || (user.occupation?.contains(searchText) ?? true)
})
}

tableView.reloadData()
}

Search bar not calling textDidChange for some reason

I got it working. Even though I specified searchBar.delegate = self in viewDidLoad, it did not work until I specified the searchBar delegate in the storyboard interface.



Related Topics



Leave a reply



Submit