New Search APIs in iOS 13

iOS has always provided interesting search APIs, but they have always been limited and doing the most interesting tasks required you to either write your own implementation or use private APIs.

iOS 13 has provided some very nice improvements to the UI search APIs. In this article we will talk about two of them.

UISearchBar finally exposes its text field

I have been using UISearchController and UISearchBar for a very long time, and I have always found it bizarre that Apple didn’t expose its underlying text field property. As of iOS 13, the search bar finally exposes it, in the form of a UISearchTextField object.

With this object, you can finally customize the appearance of the search bar. You no longer need to hack away at the view hierarchy with hopes of finding the text field and customizing it there.

searchBar.searchTextField.backgroundColor = .blue
searchBar.searchTextField.textColor = .white

There’s still some limitations, like you cannot change the bar style, but this is a very good change, and something developers have been hacking at for years. Been able to change the colors is a great improvements.

UISearchTextFieldDelegate

Along with the text field, there’s a new delegate. To tell you the truth, I have no idea what can be done with it. The Documentation only has one method that is not documented.

Search Tokens

Search Tokens are my absolutely favorite new feature for search in iOS 13. Some native Apple apps like mail have had it for years. While the API has existed for years, it has recently been opened up to developers.

Search tokens look like this:

UISearchToken

You create a search token with the UISearchToken class, and then you add them to the (also recently opened up) searchTextField properly:

let purchasesToken = UISearchToken(icon: UIImage(systemName: "tag"), text: "Purchases")
let countryToken = UISearchToken(icon: UIImage(systemName: "flag"), text: "Country")

searchBar.searchTextField.insertToken(purchasesToken, at: 0)
searchBar.searchTextField.insertToken(countryToken, at: 0)

The searchTextField lets you do more than just adding the tokens. You can change the color of the tokens (thought you cannot change them individually):

searchBar.searchTextField.tokenBackgroundColor = .blue

You can allow or prevent the user from copying and deleting tokens:

searchBar.searchTextField.allowsCopyingTokens = true
searchBar.searchTextField.allowsDeletingTokens = true

And then there’s functions to get the range of one or multiple tokens, their positions, and more, so you can build powerful search features in your app.

If you need to get the tokens themselves, the text field has a tokens property which you can access.

    searchBar.searchTextField.tokens.forEach {
      // Do something with each search token.
    }

Now here’s the bizarre thing: The tokens do not expose their text or image properties. Instead, you need to assign the representedObject property. This object is of type Any?, so you can assign it anything you need. Here we are assigning simple search terms:

purchasesToken.representedObject = "Purchases"
countryToken.representedObject = "Bolivia"

And now we can iterate over them:

searchBar.searchTextField.tokens.forEach {
  // Do something with each search token.
  print($0.representedObject)
}

Conclusion

The new search APIs are really neat in iOS 13. Other than a long-overdue functionality we have been begging for years, we also got a new beautiful tokens API, which allows to build powerful search features for our users in our apps.