Skip to main content

iOS Integration Guide

SDK version: 1.0.0
Platform: iOS (Swift / SwiftUI)
Min deployment target: iOS 16.0
Build system: Xcode 15+ / Swift Package Manager
Get your API key from app.revrag.ai → Settings → API Keys.

Table of Contents

  1. Requirements
  2. How it works
  3. Step 1 — Add the package
  4. Step 2 — Add microphone permission
  5. Step 3 — Initialize the SDK
  6. Step 4 — Identify the user
  7. Step 5 — Add the floating button
  8. Routing scenarios
  9. Button visibility control
  10. Events
  11. Analytics helpers
  12. Cleanup on logout
  13. Configuration reference
  14. Troubleshooting
  15. Pre-ship checklist

1. Requirements


Step 1 — Add the package

In Xcode: File → Add Package Dependencies Paste the URL:
Select Up to Next Major Version from 1.0.0 → select RevragEmbed → click Add Package.

CocoaPods alternative


Step 2 — Add microphone permission

Required — your app will crash at runtime without this.Without NSMicrophoneUsageDescription, iOS terminates the process the moment the SDK requests microphone access. This step cannot be skipped.
Add to Info.plist:
In Xcode: Target → Info tab → + button → Privacy - Microphone Usage Description → enter a description.

Step 3 — Initialize the SDK

Call EmbedSDK.shared.initialize() once, as early as possible.

SwiftUI App entry point

UIKit AppDelegate

What initialize() does:
  1. Calls GET /embedded-agent/initialize with your API key
  2. Parses and stores your widget configuration (colors, agent name, avatar)
  3. Pre-warms the Lottie animation cache
  4. Installs ClickEventTracker for automatic rage-click detection
  5. Sets EmbedSDK.shared.isInitialized = true on the main thread — the button appears automatically once true
Console logs are prefixed [RevragEmbed] — check them if initialization fails.

Step 4 — Identify the user

Call this right after your login flow completes:
Send USER_DATA before the user taps the call button. Without app_user_id, the agent cannot identify the user and conversation context will not be attributed.

Step 5 — Add the floating button

Apply the .embedProvider() modifier to your root view. This overlays the draggable button on top of all your existing content.

UIKit alternative

Add EmbedButton as an overlay view in your root UIViewController:

.embedProvider() modifier props


Routing scenarios

Screen tracking lets the agent know which screen the user is on. Choose the scenario that matches your navigation setup.

Scenario A — NavigationStack (most common)

Post EmbedViewDidAppear from .onAppear on each screen. The SDK listens for this notification and updates the current screen name.
Apply the provider to the root:
.onAppear fires again when navigating back to a screen — this is expected and correct behavior.

Scenario B — TabView with multiple stacks

Apply .embedProvider() outside the TabView so the button floats above all tabs. Each tab’s screens post EmbedViewDidAppear from .onAppear as shown in Scenario A.
Do not place .embedProvider() inside a tab. If it’s scoped to one tab the button will disappear when switching to other tabs.

Scenario C — No NavigationStack (flat views / custom transitions)

Fire the notification manually when your view becomes visible. You can also post EmbedViewDidDisappear on exit.

Scenario D — UIKit UINavigationController

Pass the UINavigationController to .embedProvider() for automatic tracking:
The SDK observes UINavigationControllerDelegate and fires SCREEN_STATE events automatically — no .onAppear notifications needed.

Button visibility control

By default the button shows on every screen. Use EmbedButtonVisibilityConfig to control this.

Show only on specific screens

Keep button visible across a flow (e.g. checkout)

Use a group with .continuous continuity so the button doesn’t flash between screens:

Visibility rules (evaluated in priority order)


Events

EventKeys reference

Sending events

Listen for agent call events

Agent lifecycle events reference


Analytics helpers

These helpers fire analyticsData events with standardized payloads.

Events auto-fired by the SDK


Cleanup on logout

Call this when the user logs out or switches accounts to prevent stale data from leaking into the next session.

Configuration reference

EmbedButtonVisibilityConfig

EmbedButtonGroupConfig

EmbedButtonDelayPolicy

EmbedButton direct props


Troubleshooting

App crashes on first call

Error:
Fix: Add NSMicrophoneUsageDescription to Info.plist. See Step 2 above.

The button never appears

Cause A — initialize() not called or failed Check the Xcode console for [RevragEmbed] prefixed logs:
Fix: verify your API key has no leading/trailing spaces and the device has internet.
Cause B — SDK not ready yet initialize() is async. The button is hidden until isInitialized = true and appears automatically — no action required. To observe readiness:

Cause C — Screen excluded by visibility config Screen names are case-sensitive and must match exactly what you post in EmbedViewDidAppear notifications.

Button disappears when switching tabs

Cause: .embedProvider() is applied inside a tab instead of outside the TabView.

Screen tracking not working (agent doesn’t know current screen)

Cause: EmbedViewDidAppear notification not posted from .onAppear.

Background music doesn’t resume after a call

The SDK calls AVAudioSession.setActive(false, options: .notifyOthersOnDeactivation) automatically in endCall(). If you observe this issue, ensure you are on SDK version ≥ 1.0 and that the session is not being deactivated before the SDK finishes cleaning up.

Analytics events missing from dashboard

Check in this order:
  1. USER_DATA was sent with a valid app_user_id before other events
  2. initialize() completed successfully (isInitialized == true)
  3. Device has internet connectivity
  4. The SDK rate-limits to 5 req/s — bursts are queued, not dropped

User identity leaks between accounts

Always call clearStorageCache() on logout before the next user logs in:

Pre-ship checklist

Basic setup

  • Package added via Xcode SPM: https://github.com/RevRag-ai/embed-native
  • NSMicrophoneUsageDescription added to Info.plist
  • await EmbedSDK.shared.initialize(apiKey:) called in App.init() or AppDelegate
  • USER_DATA event sent with app_user_id immediately after login
  • .embedProvider() applied to the root view (outside TabView if tabs are used)
  • clearStorageCache() called on logout

Screen tracking

  • EmbedViewDidAppear notification posted from every screen’s .onAppear (SwiftUI NavigationStack)
  • Or navigationController passed to .embedProvider() for automatic UIKit tracking
  • Screen names in notifications match visibilityConfig exactly (case-sensitive)

Visibility

  • visibilityConfig configured if the button should not show on all screens
  • .embedProvider() placed outside TabView (if applicable)

Production readiness

  • [RevragEmbed] logs checked — no initialization errors
  • Agent event listeners started and stopped at appropriate lifecycle points
  • Tested on a physical device — microphone permission dialog does not appear in Simulator

Support