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

# Loading

> Shows a loading indicator during pending search requests.

<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="true"><a className="afs-option is-current" href="/doc/api-reference/widgets/loading/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/loading/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/loading/flutter"><span className="afs-option-name">Flutter</span><span className="afs-option-lib">Algolia for Flutter</span></a></li>
    </ul>
  </div>
</div>

```ts Signature theme={"system"}
LoadingConnector(
  searcher: SingleIndexSearcher,
  interactor: LoadingInteractor,
  controller: LoadingController
)
```

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

## About this widget

Components that show a loading indicator during pending requests.

## Examples

Instantiate a `LoadingConnector`.

```swift Swift icon=code theme={"system"}
let searcher = HitsSearcher(appID: "YourApplicationID",
                            apiKey: "YourSearchOnlyAPIKey",
                            indexName: "YourIndexName")
let activityIndicatorController: ActivityIndicatorController = .init(activityIndicator: UIActivityIndicatorView())
let loadingConnector: LoadingConnector = .init(searcher: searcher,
                                               controller: activityIndicatorController)

// Execute a search which will spin the loading indicator until the results arrive
searcher.search()
```

## Parameters

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

<ParamField body="interactor" type="LoadingInteractor" post={["default: .init()"]}>
  The business logic that handles showing a loading indicator.
</ParamField>

<ParamField body="controller" type="LoadingController" post={["default: nil"]}>
  Controller that interfaces with a concrete loading view.
</ParamField>

## Low-level API

If you want to fully control the loading indicator components and connect them manually, you can use these components.

The loading indicator consists of the following components:

* `Searcher`. The [`Searcher`](/doc/api-reference/widgets/instantsearch/ios) that handles your searches.
* `LoadingInteractor`. The logic that handles showing a loading indicator
* `LoadingController`. The controller that interfaces with a concrete loading indicator.

```swift Swift icon=code theme={"system"}
let searcher = HitsSearcher(appID: "YourApplicationID",
                            apiKey: "YourSearchOnlyAPIKey",
                            indexName: "YourIndexName")
let loadingInteractor: LoadingInteractor = .init()
let activityIndicatorController: ActivityIndicatorController = .init(activityIndicator: UIActivityIndicatorView())

loadingInteractor.connectSearcher(searcher)
loadingInteractor.connectController(activityIndicatorController)

// Execute a search which will spin the loading indicator until the results arrive
searcher.search()
```

## Customizing your view

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

If you want to use another component such as a third-party view,
or want to introduce some custom behavior to the already provided UIKit components,
you can create your own controller conforming to the `LoadingController` protocol.

### Protocol

```swift Swift icon=code theme={"system"}
func setItem(_ item: Bool)`
```

Function called when a new state of the loading indicator is set.

### Example

```swift Swift icon=code theme={"system"}
public class ActivityIndicatorController: LoadingController {

  let activityIndicator: UIActivityIndicatorView

  public init (activityIndicator: UIActivityIndicatorView) {
    self.activityIndicator = activityIndicator
  }

  public func setItem(_ item: Bool) {
    item ? activityIndicator.startAnimating() : activityIndicator.stopAnimating()
  }

}
```

### SwiftUI

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

The example of the loading view using the `ProgressView` component provided by SwiftUI.

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

  @ObservedObject var loadingController: LoadingObservableController

  var body: some View {
    VStack {
      Text("Loading")
      if loadingController.isLoading {
        ProgressView()
      }
    }
  }

}
```

If you prefer to create a custom SwiftUI view that presents the loading indicator,
you can directly use the `LoadingObservableController` as a data model.
It provides the `isLoading` property to streamline the design process of your custom SwiftUI view.
