Contents

textField(_:provideUpdatedSuggestions:)

Called when the text field’s text (or tokens) have changed and when the text field is going to display a new list of suggestion items.

Declaration

@MainActor func textField(_ textField: NSTextField, provideUpdatedSuggestions responseHandler: @escaping (Self.ItemResponse) -> Void)

Parameters

  • textField:

    The text field requesting updated suggestions.

  • responseHandler:

    A closure to call with an item response when results have been gathered and are ready to display.

Discussion

Read the contents of textField to determine what suggestions to provide. For example:

func textField(
    _ textField: NSTextField,
    provideUpdatedSuggestions responseHandler: @escaping ((ItemResponse) -> Void)
) {
    // 1. Get the results (filter).
    let searchString = textField.stringValue
    let matchedLocations = self.favoriteLocations.filter({
        $0.matches(searchString: searchString)
    }).prefix(5)

    // 2. Create item representations for the results.
    let items = matchedLocations.map({
        Item(representedValue: $0, title: $0.title)
    })

    // 3. Provide them back to the text field in a titled section.
    let response = ItemResponse(itemSections: [
        ItemSection(
            title: NSLocalizedString("Favorites", comment: ),
            items: items
        ),
    ])
    responseHandler(response)
}

If some of the suggestions are time-consuming to compute, or need to be fetched from an asynchronous/remote source, call responseHandler an additional time when that data has been fetched and processed.

func textField(
    _ textField: NSTextField,
    provideUpdatedSuggestions responseHandler: @escaping ((ItemResponse) -> Void)
) {
    // …

    var response = ItemResponse()
    response.phase = .intermediate
    responseHandler(response)

    Task {
        let suggestedLocations = await LocationSuggestionsProvider.shared.suggestedLocations(for: searchString)

        response.itemSections.append(ItemSection(
            title: NSLocalizedString("Suggested Locations", comment: ),
            items: suggestedLocations.map({
                Item(representedValue: $0, title: $0.title)
            })
        ))
        response.phase = .final
        responseHandler(response)
    }
}