RelevantSort
# <!-- vale off --> # The actual component name is `interactor`, so the linting rule is ignored here RelevantSortConnector<Controller: RelevantSortController, Output>( searcher: SingleIndexSearcher, interactor: RelevantSortInteractor, controller: Controller, presenter: RelevantSortPresenter<Output> ) RelevantSortConnector<Controller: RelevantSortController, Output>( searcher: SingleIndexSearcher, interactor: RelevantSortInteractor, controller: Controller, presenter: RelevantSortTextualPresenter ) # <!-- vale on -->
About this widget
Virtual indices allow you to use Relevant sort, a sorting mechanism that favors relevancy over the attribute you’re sorting on. The relevantSort widget displays the current search mode when searching in a virtual replica index, and allows users to switch between relevant and regular sorting, which is more exhaustive and can return less relevant results.
Examples
Instantiate a RelevantSortConnector.
1
2
3
4
5
let searcher = HitsSearcher(appID: "YourApplicationID",
                            apiKey: "YourSearchOnlyAPIKey",
                            indexName: "virtual_replica_index")
let relevantSortController: ButtonRelevantSortController = .init()
let relevantSortConnector: RelevantSortConnector = .init(searcher: searcher, controller: relevantSortController)
Parameters
| Parameter | Description | 
|---|---|
          
            searcher
          
         | 
        
           
                
                type: HitsSearcher
                
               
              
                
                        Required
                
               
          The   | 
      
          
            interactor
          
         | 
        
           
                
                type: RelevantSortInteractor
                
               
              
                
                  default: .init()
                
               
              
                
                        Required
                
               
          The logic to toggle Relevant Sort.  | 
      
          
            controller
          
         | 
        
           
                
                type: RelevantSortController
                
               
              
                
                  default: nil
                
               
              
                
                    Optional
                
               
          Controller that presents and can toggle the Relevant Sort priority state.  | 
      
          
            presenter
          
         | 
        
           
                
                type: RelevantSortPresenter<Output> | RelevantSortTextualPresenter
                
               
              
                
                  default: DefaultPresenter.RelevantSort.present
                
               
              
                
                        Required
                
               
          Presenter transforming the Relevant sort priority state to its representation for a controller.  | 
      
Presenter
| Parameter | Description | ||
|---|---|---|---|
          
            RelevantSort Presenter
          
         | 
        
           
                
                type: RelevantSortPresenter<Output> | RelevantSortTextualPresenter
                
               
              
                
                  default: DefaultPresenter.RelevantSort.present
                
               
              
                
                        Required
                
               
          Presenter transforming the Relevant sort priority state to its representation for a controller. Default presenter transforms Relevant sort priority to ‘RelevantSortTextualRepresentation?’ providing a tuple of string constants in english.  | 
      ||
| 
           
Copy
 
       | 
      |||
Low-level API
If you want to fully control the RelevantSort components and connect them manually, you can use the following components:
Searcher: TheSearcherthat handles your searches.RelevantSortInteractor: Relevant sort priority toggling logic.RelevantSortController: the controller that presents and toggles the Relevant sort priority state.RelevantSortPresenter<Output>: optional. Generic presenter transforming the Relevant Sort priority state to its representation for a controller.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
let searcher = HitsSearcher(appID: "YourApplicationID",
                            apiKey: "YourSearchOnlyAPIKey",
                            indexName: "virtual_replica_index")
let relevantSortInteractor = RelevantSortInteractor()
let relevantSortController: ButtonRelevantSortController = .init()
relevantSortInteractor.connectSearcher(searcher)
let relevantSortpresenter: RelevantSortTextualPresenter = { priority in
  switch priority {
  case .some(.hitsCount):
    return ("Currently showing all results.", "Show more relevant results")
  case .some(.relevancy):
    return ("We removed some search results to show you the most relevants ones.", "Show all results")
  default:
    return nil
  }
}
relevantSortInteractor.connectController(relevantSortController, presenter: relevantSortpresenter)
Customizing your view
The controllers provided by default, like the ButtonRelevantSortController work well when you want to use native UIKit with their default behavior like a UIButton.
If you want to use another component, 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 RelevantSortController protocol.
Protocol
func setItem(_ item: RelevantSortTextualRepresentation?)
Function called when a new array of indices is defined.
var didToggle: (() -> Void)? { get set }
Closure triggered by the controller when the toggle happens (for example, toggle button clicked or switch control state changed)
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
public class RelevantSortControl: NSObject, RelevantSortController {
  public let hintLabel: UILabel
  public let toggleButton: UIButton
  public var didToggle: (() -> Void)?
  public init() {
    hintLabel = .init()
    toggleButton = .init()
    super.init()
    toggleButton.addTarget(self, action: #selector(didTapToggleButton), for: .touchUpInside)
  }
  public func setItem(_ item: RelevantSortTextualRepresentation?) {
    hintLabel.isHidden = item == nil
    toggleButton.isHidden = item == nil
    hintLabel.text = item?.hintText
    toggleButton.setTitle(item?.toggleTitle, for: .normal)
  }
  @objc func didTapToggleButton() {
    didToggle?()
  }
}
SwiftUI
InstantSearch provides the RelevantSortObservableController data model, which is an implementation of the RelevantSortController protocol adapted for usage with SwiftUI.
RelevantSortObservableController must be connected to the RelevantSortConnector or RelevantSortInteractor like any other RelevantSortController implementation.
The example of the SwiftUI view presenting the relevant sort state.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
  struct ContentView: View {
  
  @ObservedObject var relevantSortController: RelevantSortObservableController
      
  var body: some View {
    VStack {
      if let state = relevantSortController.state {
        HStack {
          Text(state.hintText)
          Spacer()
          Button(state.toggleTitle,
                 action: relevantSortController.toggle)
        }
      }
    }
  }
}
If you prefer to create a custom SwiftUI view that presents the list of facets, you can directly use the RelevantSortObservableController as a data model.
It provides the state property along with the toggle function to streamline the design process of your custom SwiftUI view.