> ## Documentation Index
> Fetch the complete documentation index at: https://algolia.com/llms.txt
> Use this file to discover all available pages before exploring further.

# SearchBox

> Lets users perform a search using text input.

export const SearchQuery = () => <Tooltip tip="The text users enter into a search box. In the Search API, this corresponds to the query parameter. A search query is often used with filters, facets, and other parameters, but these aren't part of the query text itself.">
    search query
  </Tooltip>;

```swift Signature theme={"system"}
SearchBoxConnector(
  searcher: AnyObject & Searchable & QuerySettable,
  interactor: SearchBoxInteractor,
  searchTriggeringMode: SearchTriggeringMode,
  controller: SearchBoxController
)
```

<Card title="Explore example code" icon="github" href="https://github.com/algolia/instantsearch-ios/tree/master/Examples/Showcase">
  Browse the SearchBox example code on GitHub.
</Card>

## About this widget

A component that performs a text-based <SearchQuery />.

## Examples

Instantiate a `SearchBoxConnector`.

```swift Swift icon=code theme={"system"}
let searcher = HitsSearcher(appID: "YourApplicationID",
                            apiKey: "YourSearchOnlyAPIKey",
                            indexName: "YourIndexName")
let searchBarController: SearchBarController = .init(searchBar: UISearchBar())
// If your project targets iOS 13+, you should use TextFieldController(searchBar: UISearchBar()) instead:
// let searchBarController: TextFieldController(searchBar: UISearchBar())
let searchBoxConnector: SearchBoxConnector = .init(searcher: searcher,
                                                   searchTriggeringMode: .searchAsYouType,
                                                  controller: searchBarController)
```

## Parameters

<ParamField body="searcher" type="Searcher" required>
  The [`Searcher`](/doc/api-reference/widgets/instantsearch/ios) that handles your searches.
</ParamField>

<ParamField body="interactor" type="SearchBoxInteractor" post={["default: .init()"]}>
  The logic applied to `SearchBox`.
</ParamField>

<ParamField body="searchTriggeringMode" type="SearchTriggeringMode" post={["default: .searchAsYouType"]}>
  Defines the event triggering a new search.

  * `.searchAsYouType`. Triggers a search on each keystroke.
  * `.searchOnSubmit`. Triggers a search on submitting the query.
</ParamField>

<ParamField body="controller" type="SearchBoxController" post={["default: nil"]}>
  Controller interfacing with a concrete search box view.
</ParamField>

## Low-level API

If you want to fully control the `SearchBox` components and connect them manually, you can use the following components:

* `Searcher`. The [`Searcher`](/doc/api-reference/widgets/instantsearch/ios) that handles your searches.
* `SearchBoxInteractor`. The logic that handles new search inputs.
* `SearchBoxController`. The controller interfacing with a concrete input view.

```swift Swift icon=code theme={"system"}
let searcher = HitsSearcher(appID: "YourApplicationID",
                            apiKey: "YourSearchOnlyAPIKey",
                            indexName: "YourIndexName")
let searchBoxInteractor: SearchBoxInteractor = .init()
let searchBarController: SearchBarController = .init(searchBar: UISearchBar())
// if your project targets iOS 13+, the usage of TextFieldController(searchBar: UISearchBar()) is recommended

searchBoxInteractor.connectSearcher(searcher, searchTriggeringMode: .searchAsYouType)
searchBoxInteractor.connectController(searchBarController)
```

## Customizing your view

The default controllers, `TextFieldController` and `SearchBarController`,
work well with [UIKit](https://developer.apple.com/documentation/uikit).

If you want to use another component, such as a third-party input view,
or introduce custom behaviors to UIKit components,
you can create a controller that conforms to the `SearchBoxController` protocol.

### Protocol

* `var onQueryChanged: ((String?) -> Void)?`

  Closure you should call when the query is modified.

* `var onQuerySubmitted: ((String?) -> Void)?`

  Closure you should call when the query is submitted.

* `func setQuery(_ query: String?)`

  Function called when the query is modified from the outside.

### Implementation example

```swift Swift icon=code theme={"system"}
public class TextFieldController: NSObject, SearchBoxController {

  public var onQueryChanged: ((String?) -> Void)?
  public var onQuerySubmitted: ((String?) -> Void)?

  let textField: UITextField

  public init (textField: UITextField) {
    self.textField = textField
    super.init()
    setupTextField()
  }

  public func setQuery(_ query: String?) {
    textField.text = query
  }

  @objc func textFieldTextChanged(textField: UITextField) {
    guard let searchText = textField.text else { return }
    onQueryChanged?(searchText)
  }

  private func setupTextField() {
    textField.returnKeyType = .search
    textField.addTarget(self, action: #selector(textFieldTextChanged), for: .editingChanged)
    textField.delegate = self
  }

}

extension TextFieldController: UITextFieldDelegate {

  public func textFieldShouldReturn(_ textField: UITextField) -> Bool {
    onQuerySubmitted?(textField.text)
    return true
  }

}
```

### SwiftUI

InstantSearch provides the `SearchBar` SwiftUI view, which you can embed in your views.
It uses `SearchBoxObservableController` as a data model, which implements the `SearchBoxController` protocol for SwiftUI.
`SearchBoxObservableController` must be connected to the `SearchBoxConnector` or `SearchBoxInteractor` like any other `SearchBoxController` implementation.

```swift Swift icon=code theme={"system"}
struct ContentView: View {

  @ObservedObject var searchBoxObservable: SearchBoxObservableController = .init()
  @State var isEditing = false

  var body: some View {
    SearchBar(text: $searchBoxObservable.query,
          isEditing: $isEditing,
          onSubmit: searchBoxObservable.submit)
  }

}
```

If you prefer to create a custom SwiftUI view that handles the query input,
you can directly use the `SearchBoxObservableController` as a data model.
It provides the `query` property along with the `submit` function to streamline the design process of your custom SwiftUI view.
