iOS quickstart

Last updated  Aug 4, 2026

Install the package, implement one delegate, present the assistant. Your app ships no assistant UI of its own.

The SDK is a UIKit host with a SwiftUI interior, distributed as a binary XCFramework over Swift Package Manager, targeting iOS 16 and above. Android, Flutter, and React Native follow the same four steps.

Install the SDK

Add the package in Xcode and pick the VoqalSDK library. There is nothing to vendor and no build phase to configure.

Package.swift
// File → Add Package Dependencies… → paste the URL, or add it to Package.swift:.package(url: "https://github.com/VoqalAI/voqal-ios", from: "2.0.0")

Then import VoqalSDK wherever you configure the app.

Configure at launch

Call setup once, as early as you can. Calling prewarm straight after opens the backend connection in the background so the first turn skips a cold handshake — it is a no-op until your delegate can supply a token.

AppDelegate.swift
import VoqalSDKfunc application(  _ application: UIApplication,  didFinishLaunchingWithOptions options: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {  var configuration = VoqalSDKConfiguration(    requestId: "prod-\(session.userId)",    theme: VoqalTheme(accent: "#2D5BFF", accent2: "#5EC5F1", appearance: .auto)  )  configuration.apiKey = "pk_live_…"  // sent as X-Voqal-Key  VoqalSDKManager.shared.setup(configuration: configuration)  VoqalSDKManager.shared.prewarm(delegate: coordinator)  return true}
The publishable key is not a secret.It identifies your tenant so the engine knows which prompt, tools, and theme to load. Your user's own backend token is what authorises data access, and that arrives from the delegate on every request.

Configuration options

OptionTypeRequiredDescription
requestIdStringRequiredRoutes the turn by prefix: prod- reaches your production backend, stg- reaches staging.
apiKeyString?RequiredYour publishable key, sent as X-Voqal-Key. Resolves which tenant config to load.
agentURLURL?OptionalOverrides the baked engine URL. Point it at localhost while developing.
themeVoqalThemeOptionalAccent pair, appearance (.light, .dark, .auto), and corner radius.
presentationStyleVoqalPresentationStyleOptional.sheet (default) or .fullScreen.
recordingInteractionModeRecordingInteractionModeOptionalTap-to-toggle or hold-to-talk on the mic control.

Implement the delegate

VocalButtonDelegate is the whole integration surface: five methods, all synchronous, all called on the main thread.

AppCoordinator+Voqal.swift
extension AppCoordinator: VocalButtonDelegate {  // Read live on every request — always hand back a current token.  func getToken() -> String { session.accessToken }  func getMetaData() -> String? {    #"{"country_code":"EGY","user_id":"84213"}"#  }  func getViewController() -> UIViewController { navigationController }  func voqalButton(didUploadRecording result: String) {    analytics.track("voqal_turn", result)  }  func voqalButton(didFailWith error: Error) {    logger.error("voqal", error)  }}
MethodReturnsCalled when
getToken()StringEvery request. Return your user's current backend token — the SDK never caches it.
getMetaData()String?Every request. A JSON string of client context, sent as X-Client-Metadata.
getViewController()UIViewControllerThe assistant needs a presenter, for example to push one of your own screens.
voqalButton(didUploadRecording:)VoidA voice turn finished. The payload is the transcript result.
voqalButton(didFailWith:)VoidA turn failed. Log it — the assistant has already shown the user a recoverable state.
Return a fresh token from getToken() every time. The SDK reads it live on each request rather than holding a copy, so handing back a token you captured at login will start failing the moment it expires.

Present the assistant

Open it from your own button, tab, or deep link. It comes up as a near-full sheet by default and manages its own navigation from there.

HomeViewController.swift
@objc func openAssistant() {  VoqalSDKManager.shared.presentChat(from: self, delegate: coordinator)}// Optional: forward every SDK event into your own logging.VoqalSDKManager.shared.addLogSink(VoqalConsoleLogSink())

Add NSMicrophoneUsageDescription to your Info.plist before you run — iOS terminates the app on first microphone access without it.

Next steps

You now have a working assistant. From here, most teams pick up one of these:

  • Connect your backend's MCP server so the agent answers from real data instead of general knowledge.
  • Read the widget catalogue to see what the agent can draw, and which kinds require a confirm step.
  • Attach a log sink and forward SDK diagnostics into your existing error reporting.
  • Work through the engine API if you need to drive a turn from somewhere other than an app.
© 2026 VoqalVoqal SDK & engine documentation