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

# Stats

> Shows data about the performed search.

<div className="not-prose algolia-flavor-switcher">
  <div className="afs-dropdown">
    <div className="afs-trigger" role="button" tabIndex="0" aria-haspopup="listbox">
      <span className="afs-current">iOS</span>

      <svg className="afs-chevron lucide lucide-chevron-down" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
        <path d="m6 9 6 6 6-6" />
      </svg>
    </div>

    <ul className="afs-menu" role="listbox">
      <li role="option" aria-selected="false"><a className="afs-option" href="/doc/api-reference/widgets/stats/js"><span className="afs-option-name">JavaScript</span><span className="afs-option-lib">InstantSearch.js</span></a></li>
      <li role="option" aria-selected="false"><a className="afs-option" href="/doc/api-reference/widgets/stats/react"><span className="afs-option-name">React</span><span className="afs-option-lib">React InstantSearch</span></a></li>
      <li role="option" aria-selected="false"><a className="afs-option" href="/doc/api-reference/widgets/stats/vue"><span className="afs-option-name">Vue</span><span className="afs-option-lib">Vue InstantSearch</span></a></li>
      <li role="option" aria-selected="true"><a className="afs-option is-current" href="/doc/api-reference/widgets/stats/ios"><span className="afs-option-name">iOS</span><span className="afs-option-lib">InstantSearch iOS</span></a></li>
      <li role="option" aria-selected="false"><a className="afs-option" href="/doc/api-reference/widgets/stats/android"><span className="afs-option-name">Android</span><span className="afs-option-lib">InstantSearch Android</span></a></li>
      <li role="option" aria-selected="false"><a className="afs-option" href="/doc/api-reference/widgets/stats/flutter"><span className="afs-option-name">Flutter</span><span className="afs-option-lib">Algolia for Flutter</span></a></li>
    </ul>
  </div>
</div>

{/*vale Algolia.HeadingPronouns = NO*/}

## About this widget

Each search results comes with a `SearchStats` structure containing metadata that you might display in your search experience.
The following information is available within `SearchStats`:

* `hitsPerPage`. Number of hits per page.
* `totalHitsCount`. Total number of hits.
* `pagesCount`. Total number of pages.
* `page`. Current page.
* `processingTimeMS`. Processing time of the request (in ms).
* `query`. Query text that produced these results.

InstantSearch provides two types of `StatsController`:

* `LabelStatsController`. Presents metadata in `UILabel` in the form of text.
* `AttributedLabelStatsController`. Presents metadata in `UILabel` in the form of attributed text.

The format in which metadata appears in `StatsController` is defined in the presenter closure provided while connecting the controller with `Interactor`.

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

## Examples

Instantiate a `StatsConnector` and launch an initial search on its [`Searcher`](/doc/api-reference/widgets/instantsearch/ios).

```swift Swift icon=code theme={"system"}
let searcher = HitsSearcher(appID: "YourApplicationID",
                            apiKey: "YourSearchOnlyAPIKey",
                            indexName: "YourIndexName")
let labelStatsController: LabelStatsController = LabelStatsController(label: UILabel())

let statsConnector: StatsConnector = .init(searcher: searcher,
                                           controller: labelStatsController,
                                           presenter: DefaultPresenter.Stats.present)

searcher.search()
```

## Parameters

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

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

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

<ParamField body="presenter" type="Presenter<SearchStats?, Output>" post={["default: nil"]}>
  The Presenter defining how stats appear in the controller.
</ParamField>

## Low-level API

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

* `Searcher`. The [`Searcher`](/doc/api-reference/widgets/instantsearch/ios) that handles your searches.
* `StatsInteractor`. The logic applied to the stats.
* `StatsController`. The controller that interfaces with a concrete stats view.

```swift Swift icon=code theme={"system"}
let searcher = HitsSearche(appID: "YourApplicationID",
                           apiKey: "YourSearchOnlyAPIKey",
                           indexName: "YourIndexName")
let labelStatsController: LabelStatsController = LabelStatsController(label: UILabel())
let statsInteractor: StatsInteractor = .init()
statsInteractor.connectSearcher(searcher)
statsInteractor.connectController(labelStatsController, presenter: DefaultPresenter.Stats.present)

searcher.search()
```

## Customizing your view

The default controllers, such as the `LabelStatsController`,
work well when you want to use native UIKit with their default behavior.

If you want to use another component (other than a `UILabel`) such as a `UITextView`,
a third-party view,
or want to introduce some custom behavior to the already provided UIKit component,
you can create your own controller conforming to the `StatsTextController` protocol.

### Protocol

The `setItem(_ item: String?)` method is called when new metadata are received.

### Example

```swift Swift icon=code theme={"system"}
public class LabelStatsController: StatsTextController {

  public let label: UILabel

  public init (label: UILabel) {
    self.label = label
  }

  public func setItem(_ item: String?) {
    label.text = item
  }

}
```

### SwiftUI

InstantSearch provides the `StatsTextObservableController` data model,
which is an implementation of the `StatsTextController` protocol adapted for usage with SwiftUI.
`StatsTextObservableController` must be connected to the `StatsConnector` or `StatsConnector` like any other `StatsTextController` implementation.

The example of the current filters view presenting the grouped filters.

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

  @ObservedObject var statsController: StatsTextObservableController

  var body: some View {
    Text(statsController.stats)
  }

}
```

If you prefer to create a custom textual stats SwiftUI view,
you can directly use the `StatsTextObservableController` as a data model.
It provides the `stats` property to streamline the design process of your custom SwiftUI view.
