ResolveKit
← Back to blog
Tutorial2026-05-14·8 min read

How to Add AI Support to Your iOS App in 15 Minutes

How to Add AI Support to Your iOS App in 15 Minutes

Most iOS apps still handle support the wrong way: users leave the app, open their email client, fill out a form, and wait. Every context switch is a chance they just give up and write a one-star review instead.

An embedded AI support agent changes that — the user stays in your app, gets help in the exact moment they are stuck, and the agent can actually do things, not just talk about them.

This guide shows you how to integrate the ResolveKit iOS SDK into your app, from zero to a working chat with a real tool function, in about 15 minutes.

What you get

Once the SDK is integrated, your app has:

  • **Native chat UI** — looks like part of your app, not a web view bolted on
  • **Streaming responses** — text appears in real-time, not all at once
  • **Tool execution** — the agent can call your native Swift code on the user's behalf
  • **Approval flow** — sensitive actions ask the user before running
  • **Auto-reconnect** — the session survives network drops with exponential backoff
  • **Full trace logging** — every conversation is recorded for operator review

Prerequisites

  • iOS 16+
  • Swift 5.9+ / Xcode 15+
  • A running ResolveKit backend with an API key (self-host or use the managed tier — both are free)
  • Your own LLM provider keys (the SDK does not ship with any model — you bring your own)

Step 1: Add the SDK to your project

Open Xcode and go to File → Add Package Dependencies. Enter the repository URL:

https://github.com/resolve-kit/resolvekit-ios-sdk

Or add it to your Package.swift manually:

dependencies: [
    .package(url: "https://github.com/resolve-kit/resolvekit-ios-sdk", from: "1.4.2")
],
targets: [
    .target(
        name: "YourApp",
        dependencies: [
            .product(name: "ResolveKitUI", package: "resolvekit-ios-sdk")
        ]
    )
]

Link only ResolveKitUI in your app target — it already depends on ResolveKitCore transitively.

Step 2: Define a tool function

Tool functions are how the agent can actually do things in your app — reset a password, change a setting, fetch account data. You define them as Swift structs with the @ResolveKit macro.

Here is a simple example that returns the user's current local time:

import ResolveKitAuthoring

@ResolveKit(
    name: "get_local_time",
    description: "Returns the current local time.",
    timeout: 10,
    requiresApproval: false
)
struct GetLocalTime: ResolveKitFunction {
    func perform() async throws -> String {
        let formatter = ISO8601DateFormatter()
        formatter.timeZone = .current
        formatter.formatOptions = [.withInternetDateTime, .withFractionalSeconds]
        return formatter.string(from: Date())
    }
}

A more realistic example — sending a message to a contact, which requires user approval:

@ResolveKit(
    name: "send_message",
    description: "Send a text to a contact",
    timeout: 15,
    requiresApproval: true
)
struct SendMessage: ResolveKitFunction {
    func perform(contactName: String, messageText: String, urgent: Bool) async throws -> Bool {
        // your implementation
        return true
    }
}

The @ResolveKit macro handles all the boilerplate — it generates the JSON schema, input struct, and registration glue automatically. The requiresApproval parameter controls whether the user sees a confirmation dialog before the action runs.

Step 3: Create the runtime

The runtime manages the session, connection, and tool dispatch. Configure it with your API key and the functions you want available:

import ResolveKitUI

let runtime = ResolveKitRuntime(configuration: ResolveKitConfiguration(
    apiKeyProvider: { "rk_your_api_key" },
    functions: [GetLocalTime.self]
))

Step 4: Embed the chat UI

The SDK ships with a ready-made chat view for SwiftUI, UIKit, and AppKit.

SwiftUI

import SwiftUI
import ResolveKitUI

struct ContentView: View {
    @StateObject private var runtime = ResolveKitRuntime(configuration: ResolveKitConfiguration(
        apiKeyProvider: { "rk_your_api_key" },
        functions: [GetLocalTime.self]
    ))

    var body: some View {
        ResolveKitChatView(runtime: runtime)
    }
}

ResolveKitChatView calls runtime.start() automatically when it appears. It handles connection state, streaming text, tool approval UI, and the message composer — no boilerplate needed.

UIKit

import UIKit
import ResolveKitUI

final class ChatHostViewController: UIViewController {
    private let runtime = ResolveKitRuntime(configuration: ResolveKitConfiguration(
        apiKeyProvider: { "rk_your_api_key" },
        functions: [GetLocalTime.self]
    ))

    @IBAction func openChat(_ sender: Any?) {
        let chat = ResolveKitChatViewController(runtime: runtime)
        let navigationController = UINavigationController(rootViewController: chat)
        present(navigationController, animated: true)
    }
}

How it works under the hood

When a user sends a message:

1. The SDK streams the message to your ResolveKit backend

2. The backend routes it to your LLM provider (you bring the keys)

3. The LLM responds with text and/or tool call requests

4. Streaming text appears in the chat in real-time

5. If the agent wants to call a tool, the SDK shows an approval UI (if requiresApproval is true)

6. Once approved, the SDK runs your native Swift code and sends the result back

7. The agent delivers the final response with full context

The connection is HTTP/3-based with automatic reconnect on network drops — users can switch between WiFi and cellular without losing their session.

Why not just embed a web view?

Web view-based support tools add 20-30MB to your app binary, drain battery by keeping a browser process alive, lose session state on every app switch, and cannot call native APIs. The ResolveKit SDK adds roughly 500KB, runs as native Swift, and has full access to your app's context and APIs.

What to do next

  • **Ground the agent in your docs** — upload your product documentation and screenshots to the ResolveKit dashboard so the agent understands your specific product
  • **Define more tool functions** — the more actions the agent can take, the more issues it resolves without human intervention
  • **Set approval policies** — configure which functions auto-run and which require consent, scoped by app version and user role
  • **Review session traces** — operators can see exactly what the agent did in every conversation and tune behavior from the dashboard

Related resources

  • [iOS SDK on GitHub](https://github.com/resolve-kit/resolvekit-ios-sdk) — source code, documentation, and sample app
  • [Android SDK on GitHub](https://github.com/resolve-kit/resolvekit-android-sdk) — the Android equivalent
  • [What Is an Embedded Support SDK?](/blog/what-is-embedded-support-sdk) — understand the difference between SDKs, web widgets, and help centers
  • [Start Free](https://console.resolvekit.app/login?mode=register) — spin up a managed backend in minutes

Ready to build better in-app support?

ResolveKit is an open-source SDK for embedding AI support directly in your mobile app.