# Advanced | Swift AI Autocomplete Docs

> For the complete documentation index, see [llms.txt](https://ai-autocomplete.com/llms.txt). A markdown version of any page on this site is available by appending `.md` to its URL path — the homepage is at `/index.md`.

Advanced guide for integrating the AI Autocomplete SDK with Swift. Code examples, setup, and API reference.

Source: https://ai-autocomplete.com/docs/swift/advanced

---

Patterns for power users — client-side options, re-edit behavior, LLM-identified params, error handling, and accessibility.

## Inject field options at runtime

Fields whose options come from your own data (a location search, a customer list, live inventory) have their own guide. [Field Injection](https://ai-autocomplete.com/docs/swift/field-injection) walks through marking a field as injected in Edit Logic and wiring optionOverrides to your endpoint.

## Personalize suggestions per user

Suggestions can be tailored to each user with what your app already knows about them: a profile, saved preferences, recent activity. [Personalization](https://ai-autocomplete.com/docs/swift/personalization) covers what to send, how to keep it current, the size cap, and what stays private.

## Re-editing completed params

Filled pills stay editable — the full views handle all of this for you:

-   Tapping a completed param (or moving the caret inside it) enters re-edit mode and reopens its cached options — no refetch.
-   Picking a different option replaces the param's text atomically, then refetches suggestions — everything suggested after that param was conditioned on the value you just replaced.
-   Deleting through a pill's edge removes the whole param; removeLastParam() does the same programmatically.

## LLM-identified params

The server can recognize a span the user typed themselves as a parameter — no option tap involved. The full views render these as chips automatically; headless consumers read them from controller.identifiedParams and the .identified segment case.

-   Identified chips are tentative: each response replaces the set, and a chip disappears as soon as its text is edited away or a completed param claims the span.
-   They are not re-editable — there are no cached options behind them — so Backspace at a chip's trailing edge deletes it whole in one press. Custom inputs get the same behavior from removeIdentifiedParam(atCaret:).
-   They're echoed to the server on the next request so it keeps resolving the same span, but they are never placeholder-substituted into rawQuery — only completed params are.

## Error handling

Every terminal failure reaches onError as a typed AIAutocompleteError — match on the cases you care about.

**ErrorHandling.swift**

```swift
AIAutocompleteController.Configuration(
    apiConfig: .apiKey(.init(apiKey: "pk_v1_your_public_key")),
    onError: { error in
        switch error {
        case .network(let urlError):
            print("Offline or timed out: \(urlError)")
        case .http(let status, let message):
            print("Server returned \(status): \(message ?? "")")
        case .unauthorized:
            print("Token rejected twice — re-authenticate")
        case .tokenProvider(let underlying):
            print("getAccessToken threw: \(underlying)")
        default:
            print("Unexpected: \(error)")
        }
    }
)
```

Cancelled fetches (superseded by newer keystrokes) are consumed internally and never reach onError. The controller also mirrors the last error on its error property — clear it with dismissError().

## Accessibility

The views are built on UIKit text and collection primitives and respect system accessibility settings:

-   Dynamic Type: all SDK text scales with the user's setting; option text is clamped at maximumContentSizeCategory.
-   Reduce Motion: always wins over the animations token — visual effects stop while the rest of the UI behaves identically.
-   Haptics: the promotion tick respects the haptics switch and is independent of animations, so Reduce Motion users keep the tactile cue.
