iOS SDK 1.2.2

Voqal iOS SDK 1.2.2

The voice-first, render-spec SDK — drop in the assistant, point it at your backend, and ship a themed voice + chat experience.

Looking for the legacy SDK docs?

Integration

  1. In Xcode, choose File → Add Package Dependencies…
  2. Enter the package URL: https://github.com/VoqalAI/voqal-ios and add the VoqalSDK library.
  3. Set the dependency rule to Up to Next Major from 1.2.2.
  4. Minimum deployment target: iOS 16. Add NSMicrophoneUsageDescription and NSFaceIDUsageDescription to your Info.plist (mic for voice, Face ID for high-risk confirmations).

Setup

Step 1: Provide credentials via a delegate

Conform to VocalButtonDelegate. The SDK reads the auth token live on every request, so always return a currently-valid token — refresh it before it expires.

ViewController.swiftswift
import VoqalSDK

extension ViewController: VocalButtonDelegate {
    // Your end-user's auth token for the MCP backend (kept fresh by your app).
    func getToken() -> String { authStore.currentToken }

    // Optional JSON: country, user id, etc. Drives region + personalization.
    func getMetaData() -> String? {
        #"{"country_code":"EGY","user_id":"285"}"#
    }

    // The view controller the assistant is presented from.
    func getViewController() -> UIViewController { self }
    func voqalButton(didUploadRecording result: String) {}   // recording lifecycle
    func voqalButton(didFailWith error: Error) {}
}

Step 2: Configure & register the SDK

Build a VoqalSDKConfiguration, set your API key and theme, then register it once at launch.

AppDelegate.swiftswift
import VoqalSDK

func application(_ application: UIApplication,
                didFinishLaunchingWithOptions launchOptions: [...]?) -> Bool {

    var config = VoqalSDKConfiguration(requestId: "prod-yourapp")
    config.apiKey = "pk_live_…"            // your Voqal API key (required)
    config.theme  = VoqalTheme(accent: "#2d5bff", accent2: "#5b8dff",
                               appearance: .auto)
    config.home   = VoqalHome(
        userName: "Nour",
        pinnedCTAs: ["What's my balance?", "Create a payment link"])

    VoqalSDKManager.shared.setup(configuration: config)
    // Optional but recommended: warm the engine in the background so the
    // assistant answers instantly the first time it opens. Pass any object
    // conforming to VocalButtonDelegate (see the next step).
    VoqalSDKManager.shared.prewarm(delegate: voqalDelegate)
    return true
}
requestId selects the environment by prefix: prod- → production, stg- → staging.

Presenting the assistant

Two ways to open it — use the built-in orb button, or present it yourself from any of your own buttons.

Option A — the Voqal orb button

ViewController.swiftswift
let voqal = VoqalButton()
voqal.delegate = self            // your VocalButtonDelegate
view.addSubview(voqal)           // tapping it opens the assistant

Option B — present from any button

ViewController.swiftswift
@objc func openAssistant() {
    VoqalSDKManager.shared.presentChat(
        from: self,           // any UIViewController
        delegate: self,       // your VocalButtonDelegate
        animated: true)
}

Complete example

Everything together — register the SDK at launch, present it from your own button, and supply credentials live.

VoqalIntegration.swiftswift
import UIKit
import VoqalSDK

// 1) Register the SDK once at launch.
@main
class AppDelegate: UIResponder, UIApplicationDelegate {
    // Retained so prewarm's background task always has live credentials.
    let voqalDelegate = VoqalCredentialsDelegate()

    func application(_ application: UIApplication,
                     didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {

        var config = VoqalSDKConfiguration(requestId: "prod-yourapp")  // "prod-" / "stg-"
        config.apiKey = "pk_live_…"                                    // your Voqal API key
        config.theme  = VoqalTheme(accent: "#2d5bff", accent2: "#5b8dff",
                                   appearance: .auto)
        config.home   = VoqalHome(userName: "Nour",
                                  pinnedCTAs: ["What's my balance?", "Create a payment link"])

        VoqalSDKManager.shared.setup(configuration: config)
        VoqalSDKManager.shared.prewarm(delegate: voqalDelegate)   // warm the engine at launch

        #if DEBUG
        VoqalSDKManager.shared.addLogSink(VoqalConsoleLogSink())       // log every event/error
        #endif
        return true
    }
}

// 2) Open the assistant from any of your own buttons.
final class HomeViewController: UIViewController {
    let voqal = VoqalCredentialsDelegate()
    @objc func openAssistant() {
        VoqalSDKManager.shared.presentChat(from: self, delegate: voqal, animated: true)
    }
}

// 3) Supply credentials live — the SDK reads these on every request.
final class VoqalCredentialsDelegate: NSObject, VocalButtonDelegate {
    func getToken() -> String { TokenStore.shared.current }   // keep this token fresh
    func getMetaData() -> String? { #"{"country_code":"EGY","user_id":"285"}"# }
    func getViewController() -> UIViewController {
        UIApplication.shared.connectedScenes
            .compactMap { ($0 as? UIWindowScene)?.keyWindow?.rootViewController }
            .first ?? UIViewController()
    }
    func voqalButton(didUploadRecording result: String) {}   // recording lifecycle
    func voqalButton(didFailWith error: Error) {}
}

Theming

One VoqalTheme drives the whole experience. Surfaces, hairlines and text tiers are derived automatically so it looks native in light or dark.

Theme.swiftswift
config.theme = VoqalTheme(
    accent: "#2d5bff",        // your brand color (hex)
    accent2: "#5b8dff",       // optional gradient pair
    appearance: .auto,        // .light · .dark · .auto (follows the phone)
    fontName: nil,            // optional custom display font
    radius: 20)               // base corner radius for cards & the sheet

Customization

  • Home screenVoqalHome(userName:pinnedCTAs:showAgentGlance:): the greeting name, the "Try saying" suggestions, and whether to show the live data glance.
  • Header titleconfig.strings.chatHeaderTitle (defaults to "Voqal").
  • Iconsconfig.icons.chatHeaderIcon (header mark) and config.icons.voqalButtonIcon (the launcher). Leave unset for the accent orb.
  • Fast first turn — call VoqalSDKManager.shared.prewarm(delegate:) right after setup: it opens the engine connection in the background so the assistant is instant when the user opens it.
  • Conversation memoryconfig.conversationTimeout (default 2h): how long a conversation resumes after the sheet is closed & reopened.

Configuration reference

PropertyTypeDefaultDescription
requestIdStringrequiredEnvironment routing — prod- or stg- prefix.
apiKeyStringrequiredYour Voqal API key (pk_live_…), sent as X-Voqal-Key.
themeVoqalThemedefaultaccent, accent2, appearance (.light/.dark/.auto), fontName, radius.
homeVoqalHomeemptyuserName, pinnedCTAs, showAgentGlance.
strings…StringsConfiguration"Voqal"chatHeaderTitle — the assistant's name in the header.
icons…IconConfigurationaccent orbchatHeaderIcon, voqalButtonIcon.
conversationTimeoutTimeInterval7200How long a conversation resumes after close/reopen (seconds).
agentURLURL?baked inOverride the engine endpoint (rarely needed).

API key & security

  • Every app needs a Voqal API key (pk_live_…), set on config.apiKey. We issue one per integrator — requests without a valid key are rejected.
  • Each session establishes a device key in the Secure Enclave and signs every request (proof-of-possession), so a leaked session token is useless without the device.
  • Money-movement actions are never executed inline — they surface a confirm card first. High-risk actions (e.g. instant settlement) additionally require Face ID; lower-risk ones (e.g. creating a payment link) are a single tap.
  • Session tokens refresh automatically and silently — no error is shown to the user.

Diagnostics

  • VoqalSDK includes built-in crash and error reporting so issues are detected and resolved quickly. It works automatically — no setup required.
  • It is privacy-preserving: auth tokens and personal data are never sent. You may wish to note the presence of in-app diagnostics in your privacy policy.

Need an API key?

We issue a Voqal API key per integrator. Reach out and we'll get you set up, or check the SDK repository for the latest release.