UISearchBar example with Swift and Parse

In this video I am going to share with you how to create a search feature for your Swift mobile application that uses Parse Cloud as it’s mobile app backend. I will also show you how to run case sensitive and case insensitive search using Parse SDK.

To perform case sensitive search query against the custom Parse Class with a name “Friends”:

var firstNameQuery = PFQuery(className:”Friends”)
firstNameQuery.whereKey(“first_name”, containsString: searchBar.text)
var lastNameQuery = PFQuery(className:”Friends”)
lastNameQuery.whereKey(“last_name”, containsString: searchBar.text)
var query = PFQuery.orQueryWithSubqueries([firstNameQuery, lastNameQuery])
query.findObjectsInBackgroundWithBlock {
(results: [AnyObject]?, error: NSError?) -> Void in
if error != nil
{
// Display error message
return
}
if let objects = results as? [PFObject] {
self.searchResults.removeAll(keepCapacity: false)
for object in objects {
let firstName = object.objectForKey(“first_name”) as! String
let lastName = object.objectForKey(“last_name”) as! String
let fullName = firstName + ” ” + lastNameself.searchResults.append(fullName)
}dispatch_async(dispatch_get_main_queue()) {
self.myTable.reloadData()
self.mySearchBar.resignFirstResponder()}
}}

To perform case insensitive search query against the custom Parse Class with a name “Friends”:

var firstNameQuery = PFQuery(className:”Friends”)
lastNameQuery.whereKey(“first_name”, matchesRegex: “(?i)\(searchBar.text)”)
var lastNameQuery = PFQuery(className:”Friends”)
lastNameQuery.whereKey(“last_name”, matchesRegex: “(?i)\(searchBar.text)”)
var query = PFQuery.orQueryWithSubqueries([firstNameQuery, lastNameQuery])
query.findObjectsInBackgroundWithBlock {
(results: [AnyObject]?, error: NSError?) -> Void in
if error != nil
{
// Display error message
return
}
if let objects = results as? [PFObject] {
self.searchResults.removeAll(keepCapacity: false)
for object in objects {
let firstName = object.objectForKey(“first_name”) as! String
let lastName = object.objectForKey(“last_name”) as! String
let fullName = firstName + ” ” + lastNameself.searchResults.append(fullName)
}dispatch_async(dispatch_get_main_queue()) {
self.myTable.reloadData()
self.mySearchBar.resignFirstResponder()}
}}

Download source code.

  • Joey Bodnar

    this is really good, thanks a lot!!

  • Fırat Atalay

    where can i get how “matchesRegex” part of your code works? I mean, I want to make use of insensitive search in my app. I followed you steps almost exactly, but as I’m typing lastNameQuery.whereKey(“xyz”, [HERE]) matchesRegex doesn’t appear in suggestions.

    By the way your tutorials helped me a lot! Thank you in advance!

    • Firat, I have double checked it and matchesRegex is still part of PFQuery. Do you see any red highlights above this line?

  • sokhim khung

    func searchBarSearchButtonClicked(searchBar: UISearchBar)
    {
    mySearchBar.resignFirstResponder()
    let queryFirstName = PFQuery(className: “friends”)
    // queryFirstName.whereKey(“first_name”, containsString: searchBar.text)
    queryFirstName.whereKey(“first_name”, matchesRegex: “(?i)(searchBar.text)”)
    let queryLastNmae = PFQuery(className: “friends”)
    // queryLastNmae.whereKey(“last_name”, containsString: searchBar.text)
    queryLastNmae.whereKey(“last_name”, matchesRegex: “(?i)(searchBar.text)”)
    let query = PFQuery.orQueryWithSubqueries([queryFirstName, queryLastNmae])
    query.findObjectsInBackgroundWithBlock { (results: [PFObject]?, error: NSError? ) -> Void in
    if error != nil {
    let alertMessage:UIAlertController = UIAlertController(title: “Alert”, message: error?.localizedDescription, preferredStyle: UIAlertControllerStyle.Alert)
    let okAction = UIAlertAction(title: “OK”, style: UIAlertActionStyle.Default, handler: nil )
    alertMessage.addAction(okAction)
    self.presentViewController(alertMessage, animated: true, completion: nil )

    return

    }

    if let objects = results {
    for object in objects {

    self.mySearchResult.removeAll(keepCapacity: false)
    let firstName = object.objectForKey(“first_name”)as! String
    let lastName = object.objectForKey(“last_name”) as! String
    let fullName = firstName + ” ” + lastName

    self.mySearchResult.append(fullName)
    }

    dispatch_async(dispatch_get_main_queue(),{
    self.myTable.reloadData()

    self.mySearchBar.resignFirstResponder()
    })
    }
    }
    }

  • i tried with this function. Unfortunately search return empty by using “matchesRegex”

  • func searchBarSearchButtonClicked(searchBar: UISearchBar)

    {
    mySearchBar.resignFirstResponder()
    let queryFirstName = PFQuery(className: “friends”)
    // queryFirstName.whereKey(“first_name”, containsString: searchBar.text)
    queryFirstName.whereKey(“first_name”, matchesRegex: “(?i)(searchBar.text)”)
    let queryLastNmae = PFQuery(className: “friends”)
    // queryLastNmae.whereKey(“last_name”, containsString: searchBar.text)
    queryLastNmae.whereKey(“last_name”, matchesRegex: “(?i)(searchBar.text)”)
    let query = PFQuery.orQueryWithSubqueries([queryFirstName, queryLastNmae])
    query.findObjectsInBackgroundWithBlock { (results: [PFObject]?, error: NSError? ) -> Void in
    if error != nil {
    let alertMessage:UIAlertController = UIAlertController(title: “Alert”, message: error?.localizedDescription, preferredStyle: UIAlertControllerStyle.Alert)
    let okAction = UIAlertAction(title: “OK”, style: UIAlertActionStyle.Default, handler: nil )
    alertMessage.addAction(okAction)
    self.presentViewController(alertMessage, animated: true, completion: nil )

    return

    }

    if let objects = results {
    for object in objects {

    self.mySearchResult.removeAll(keepCapacity: false)
    let firstName = object.objectForKey(“first_name”)as! String
    let lastName = object.objectForKey(“last_name”) as! String
    let fullName = firstName + ” ” + lastName

    self.mySearchResult.append(fullName)
    }

    dispatch_async(dispatch_get_main_queue(),{
    self.myTable.reloadData()

    self.mySearchBar.resignFirstResponder()
    })
    }
    }
    }

    • Sokhim, please add exlamation mark after the searchBar.text when you reference it. Like so:

      queryFirstName.whereKey(“first_name”, matchesRegex: “(?i)(searchBar.text!)”)

      Please note exclamation mark at the end of .text

      • Ohhh, Now i can search already.Many Thanks you!!! Mr.Sergery

  • i tried this function by “matchesRegex” as below Unfortunately search is empty.

  • One more case when search return only one record whether in parse have data 2 row is the same last_name.

    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return mySearchResult.count

    }

  • tried to search.

    • Can you show me a screenshot of your code rather than pasting it here? There must be something wrong… Other wise it should work I do not see a mistake.

      • help me to check its. Thanks you in advance.

        • I see… please take this line out of the “for loop”:
          self.searchResults.removeAll(keepCapacity: false)

          move it one level up. It should be inside “IF” but before “FOR LOOP”
          and it will work.

          • it’s work well. i am very appreciated your promptly supported. MR.Sergey.

          • Awesome! 🙂 If you like you can subscribe to my blog to receive free video tutorials every week. I have also published a mini book this week and it’s price is $0.98 🙂 Check it out on Amazon.com here: http://goo.gl/dIBKpv

          • Yes, i am subscriber this blog.
            Anyway I would be working with you whether have an opportunity for apply to cambodia market.

  • I keep getting a “cannot convert value of type ‘([AnyObject)?, NSError?) -> Void..” for the query.findObjectsInBackgroundWithBlock How can I fix this?