Serve a field's options from your own data (an airport search, a customer list, live inventory) while AI Autocomplete keeps guiding the rest of the query.
How it works
You mark a field as injected in Edit Logic, then hand the SDK a function for it. Whenever that field becomes the active pill, the SDK asks your function for options instead of using its own. For a travel booking flow with a location field, one round looks like this:
- The user types, and AI Autocomplete suggests the next field to fill. Here, that is location.
- Because location is injected, the SDK calls your function with what the user has typed for it so far ("" at first, then "SF"). Your function can call your own search endpoint.
- Whatever you return is shown in the dropdown as-is, so a fuzzy match your endpoint found (Oakland for "SF") is never hidden.
- The user picks an option (or types one out in full) and the field completes. AI Autocomplete suggests the next field, and its own options take over again.
Step 1: Mark the field as injected
AI Autocomplete needs to know which fields you own, so it can suggest them at the right moment and leave their options to you.
- Open Edit Logic and answer Yes to the custom data fields question.
- Add a field and give it the name you will use in code, for example location.
- Pick "I will inject the values at runtime" as its type.
- Save. Your product regenerates with the new field, and the SDK surfaces it as a pill whenever the query calls for it.
Step 2: Connect your data
Pass optionOverrides with one entry per injected field. Each entry is a function that:
- Receives the text the user has typed for that field.
- Returns the options to show, synchronously.
- Should read data that is already in memory. Load or prefetch your list ahead of time and filter it here.
// "location" added as a runtime-injected custom field in Edit Logic.// The key must match the field name exactly as typed there.//// The closure is synchronous: load your airports up front (or keep a// warm cache) and filter here. "SF" can match SFO and nearby Oakland.let airports: [Airport] = AirportIndex.shared.alllet configuration = AIAutocompleteController.Configuration(apiConfig: .apiKey(.init(apiKey: "pk_v1_your_public_key")),optionOverrides: ["location": { query inairports.filter { query.isEmpty || $0.matches(query) }.prefix(8).map { SuggestionOption(text: "\($0.city) (\($0.code))", isTappable: true) }}])
Fixed and computed lists
Not every injected field needs a request. Return an array directly for a list you already have, or compute options from what the user typed.
optionOverrides: ["cabin": { _ in["Economy", "Premium economy", "Business"].map { SuggestionOption(text: $0, isTappable: true) }},"travelers": { query inlet digits = query.filter(\.isNumber)let label = digits.isEmpty ? "2 travelers" : "\(digits) travelers"return [SuggestionOption(text: label, isTappable: true)]}]
What the SDK does with your answer
- Your function is called the moment the field becomes active, with whatever the user has already typed for it (usually "", the request for the default list). It is called again with each new phrase after the SDK's typing debounce.
- The list you return is shown as-is. The SDK does not filter it again by the phrase it was produced for, so a match your endpoint found (Oakland for "SF") stays visible.
- Between two calls, the SDK filters your last answer locally by what the user types, so the dropdown keeps up on every keystroke.
- While an answer is pending, the dropdown shows its loading state and isLoading is true, the same flag it raises while waiting on AI Autocomplete.
- Picking an option, or typing an option's text out in full, completes the field. AI Autocomplete then suggests the next field, and its own options take over until another injected field comes up.
When nothing matches
Return an empty list for something the user typed and the SDK stops waiting on you for that phrase:
- The typed text is handed to AI Autocomplete, which treats it like any field with no matching options, so the user is never stuck.
- You are asked again as soon as the phrase changes.
- An empty list for "" (the default-list request) leaves the field on screen with no options until the user types something.
Cancellation and errors
- Keep the closure fast: it runs on the main thread for every phrase. Filter an in-memory list rather than doing work that blocks.
- A thrown error or rejected promise is contained: it is logged once and treated as an empty answer. It never surfaces as a fetch error or breaks the widget.
Option shape
Each entry you return is a suggestion option, the same shape AI Autocomplete's own options use.
| Prop | Type | Description |
|---|---|---|
textRequired | String | Label shown in the dropdown, and inserted into the query when picked. |
isTappableRequired | Bool | true for an option the user can pick. false renders it as a non-interactive hint (hidden entirely when showNonTappableOptions is false). |