API Reference / InstantSearch iOS / Dynamic Facet List
Signature
DynamicFacetListConnector(
  searcher: Searcher,
  filterState: FilterState,
  orderedFacets: [AttributedFacets],
  selections: [Attribute: Set<String>],
  selectionModeForAttribute: [Attribute: SelectionMode],
  filterGroupForAttribute: [Attribute: FilterGroupDescriptor],
  controller: DynamicFacetListController
)

About this widget

DynamicFacetList is a view that displays the ordered list of facets and facet values. The order of groups and facet values in each group is defined by the corresponding settings of the index and may be altered by a Rule. You can configure the facet merchandising through the corresponding index setting.

Learn how to set up ordering in the facet display guide.

Requirements

You must set the following:

  • Attributes for faceting attributesForFaceting and configure the facet order, either using the dashboard or using attributesForFaceting and rendering content with the API.
  • facets property of the query using Searcher.request.query.facets providing the facet attributes you want to retrieve.

You must use at least InstantSearch iOS version 7.12.0 to use Dynamic Facet List.

Examples

Instantiate a DynamicFacetListConnector, set the query facets and launch an initial search on its searcher.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
let searcher = HitsSeacher(appID: "YourApplicationID", 
                           apiKey: "YourSearchOnlyAPIKey", 
                           indexName: "YourIndexName")
searcher.request.query.facets = ["brand", "color", "size", "country"]

let filterState = FilterState()
let dynamicFacetListController = DynamicFacetListTableViewController()

let dynamicFacetlistConnector = DynamicFacetListConnector(searcher: searcher,
                                                          filterState: filterState,
                                                          selectionModeForAttribute: [
                                                            "color": .multiple,
                                                            "country": .multiple
                                                          ],
                                                          filterGroupForAttribute: [
                                                            "brand": ("brand", .or),
                                                            "color" : ("color", .or),
                                                          ],
                                                          controller: dynamicFacetListController)

searcher.connectFilterState(filterState)
searcher.search()

Parameters

searcher
type: Searcher
Required

The Searcher that handles your searches.

filterState
type: FilterState
Required

The FilterState that holds your filters.

orderedFacets
type: [AttributedFacets]
default: []
Optional

The ordered list of attributed facets.

selections
type: [Attribute: Set<String>]
default: []
Optional

The mapping between a facet attribute and a set of selected facet values.

selectionModeForAttribute
type: [Attribute: SelectionMode]
default: [:]
Optional

The mapping between a facet attribute and a facet values selection mode. If not provided, the default selection mode is .single.

filterGroupForAttribute
type: [Attribute: FilterGroupDescriptor]
default: [:]
Optional

The mapping between a facet attribute and a descriptor of a filter group where the corresponding facet filters are stored in the filter state.

controller
type: DynamicFacetListController
Optional

DynamicFacetListController implementation to connect.

Low-level API

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

  • Searcher: the Searcher that handles your searches.
  • FilterState: the current state of the filters.
  • DynamicFacetListInteractor: dynamic facet list business logic
  • DynamicFacetListController: controller presenting the ordered list of facets and handling the user interaction
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
let searcher = HitsSearcher(appID: "YourApplicationID", 
                            apiKey: "YourSearchOnlyAPIKey", 
                            indexName: "YourIndexName")
searcher.request.query.facets = ["brand", "color", "size", "country"]

let filterState = FilterState()
let dynamicFacetListController = DynamicFacetListTableViewController()

let dynamicFacetListInteractor = DynamicFacetListInteractor(selectionModeForAttribute: [
                                                              "color": .multiple,
                                                              "country": .multiple
                                                            ])

dynamicFacetListInteractor.connectSearcher(searcher)
dynamicFacetListInteractor.connectFilterState(filterState, filterGroupForAttribute: [
                                                             "brand": ("brand", .or),
                                                             "color" : ("color", .or),
                                                           ])
dynamicFacetListInteractor.connectController(dynamicFacetListController)

searcher.connectFilterState(filterState)
searcher.search()

Customizing your view

UIKit

InstantSearch iOS provides the DynamicFacetListTableViewController, which is the UITableViewController subclass that implements the DynamicFacetListController protocol. If you want to use another component, such as a UICollectionView or a third-party view, or if you want to introduce some custom behavior to the already provided UIKit component, you can create your own controller conforming to the DynamicFacetListController protocol.

Protocol

func setOrderedFacets(_ orderedFacets: [AttributedFacets]) Update the list of the ordered attributed facets

func setSelections(_ selections: [Attribute: Set<String>]) Update the facet selections

var didSelect: ((Attribute, Facet) -> Void)? Closure to trigger when user selects a facet

SwiftUI

InstantSearch iOS provides the DynamicFacetListObservableController, an implementation of the DynamicFacetListController protocol adapted for usage with SwiftUI. It provides orderedFacets and selections properties with convenient toggle and isSelected functions which allow you to implement your own SwiftUI view.

Implementation example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
struct ContentView: View {
  
  @ObservedObject var dynamicFacetListController: DynamicFacetListObservableController
    
  var body: some View {
    ScrollView {
      ForEach(dynamicFacetListController.orderedFacets, id: \.attribute) { orderedFacet in
        VStack(spacing: 0) {
          // Facet header
          ZStack {
            Color(.systemGray5)
            Text(orderedFacet.attribute.rawValue)
              .fontWeight(.semibold)
              .frame(maxWidth: .infinity, alignment: .leading)
              .padding(.horizontal, 5)
          }
          // Facet values
          ForEach(orderedFacet.facets, id: \.value) { facet in
            VStack(spacing: 0) {
              FacetRow(facet: facet,
                      isSelected: dynamicFacetListController.isSelected(facet, for: orderedFacet.attribute))
                .onTapGesture {
                  dynamicFacetListController.toggle(facet, for: orderedFacet.attribute)
                }
                .frame(minHeight: 44, idealHeight: 44, maxHeight: .infinity, alignment: .center)
                .padding(.horizontal, 5)
            }
          }
        }
      }
    }
  }
  
}

Check out the example to see this widget in action.

Did you find this page helpful?