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

# QueryRuleCustomData

> Shows custom data from applied index rules.

## About this widget

The `QueryRuleCustomData` widget displays custom data from [rules](/doc/guides/managing-results/rules/detecting-intent).

You may want to use this widget to display banners or recommendations returned by Rules, and that match search parameters.

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

## Examples

Instantiate a `QueryRuleCustomDataConnector` and launch an initial search on its [`Searcher`](/doc/api-reference/widgets/instantsearch/ios) triggering a Rule that returns custom data.

```swift Swift icon=code theme={"system"}
let searcher = HitsSearcher(appID: "YourApplicationID",
                            apiKey: "YourSearchOnlyAPIKey",
                            indexName: "YourIndexName")
let bannerViewController = BannerViewController()
let queryRuleCustomDataConnector = QueryRuleCustomDataConnector<Banner>(searcher: searcher,
                                                                        controller: bannerViewController)

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="QueryRuleCustomDataInteractor<Model>" post={["default: .init()"]} required>
  The logic applied to the custom model.
</ParamField>

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

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

## Low-level API

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

* `Searcher`. The [`Searcher`](/doc/api-reference/widgets/instantsearch/ios) that handles your searches.
* `QueryRuleCustomDataInteractor`. The logic applied to the custom model.
* `ItemController`. The Controller interfacing with a concrete custom data view.

```swift Swift icon=code theme={"system"}
let searcher = HitsSearcher(appID: "YourApplicationID",
                            apiKey: "YourSearchOnlyAPIKey",
                            indexName: "YourIndexName")
let queryRuleCustomDataInteractor: QueryRuleCustomDataInteractor<Banner> = .init()
let bannerViewController: BannerViewController = .init()

queryRuleCustomDataInteractor.connectSearcher(searcher)
queryRuleCustomDataInteractor.connectController(bannerViewController)
```

## Customizing your view

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

### Protocol

`func setItem(_ item: String?)`:

Function called when new metadata are received.

### Example

Suppose your custom JSON data contains a banner URL that can be decoded to the following structure:

```swift Swift icon=code theme={"system"}
struct Banner: Decodable {
  let bannerURL: URL
}
```

You could implement the `BannerViewController` presenting the banner image as follows:

```swift Swift icon=code theme={"system"}
class BannerViewController: UIViewController, ItemController {

  let bannerView: UIImageView = .init()

  override func viewDidLoad() {
    super.viewDidLoad()
    // some setup layout code
  }

  func setItem(_ item: Banner?) {
    guard let bannerURL = item?.bannerURL else {
      bannerView.image = nil
      return
    }
    URLSession.shared.dataTask(with: bannerURL) { (data, _, _) in
      self.bannerView.image = data.flatMap(UIImage.init)
    }.resume()
  }

}
```

### SwiftUI

To create a rule custom data view with SwiftUI start with implementation of the `ItemController` containing your custom model as a published property.

```swift Swift icon=code theme={"system"}
class BannerObservableController: ObservableObject, ItemController {

  @Published var banner: Banner?

  func setItem(_ item: Banner?) {
    self.banner = item
  }

}
```

Then connect this controller to the `QueryRuleCustomDataConnector` or `QueryRuleCustomDataInteractor` and build a SwiftUI view presenting the fetched custom model.

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

  @ObservedObject var bannerController: BannerObservableController

  var body: some View {
    if let bannerURL = bannerController.banner?.bannerURL {
      // present a banner using the fetched URL
    }
  }

}
```
