Mobile Widget SDKs

# iOS

Use the binary Swift package to host Returning.AI custom widgets in SwiftUI or UIKit applications.

Package repository: [ReturningAI/returningai-widget-swift-sdk](https://github.com/ReturningAI/returningai-widget-swift-sdk)

> Repository access is currently required
>
> The Swift package repository is private. Xcode and SwiftPM need a GitHub account or token with repository access until Returning.AI makes the package public.

## Requirements

- iOS 15 or later and Swift tools 6.0.
- An HTTPS client origin allowlisted for the target widget.
- A trusted backend that returns freshly minted embed tokens.
- Repository access for the current private Swift package.

## Add the Swift package

In Xcode, choose **File → Add Package Dependencies** and enter the repository URL above. Select exact version `0.1.1`. A host package can declare the same dependency directly.

`Package.swift`

```swift
.package(
    url: "https://github.com/ReturningAI/returningai-widget-swift-sdk.git",
    exact: "0.1.1"
)
```

Add `ReturningAIWidget` for UIKit. Add both `ReturningAIWidget` and `ReturningAIWidgetSwiftUI` for SwiftUI.

## SwiftUI

Keep the controller with the host screen and fetch embed tokens through the application backend.

`RewardsView.swift`

```swift
import ReturningAIWidget
import ReturningAIWidgetSwiftUI

let controller = ReturningAIWidgetController()
let configuration = ReturningAIWidgetConfiguration.customBundle(
    widgetId: "YOUR_SUPPLIED_WIDGET_ID",
    bundleURL: URL(string: "YOUR_SUPPLIED_BUNDLE_URL")!,
    clientOrigin: URL(string: "https://mobile-client.example")!,
    runtimeURL: URL(
        string: "https://unpkg.com/@returningai/widget-sdk/dist/rai-widget.iife.js"
    )!
)

ReturningAIWidgetSwiftUI.ReturningAIWidget(
    configuration: configuration,
    embedTokenProvider: {
        try await backend.fetchReturningAIEmbedToken()
    },
    controller: controller,
    onExternalNavigation: { url in
        appRouter.openExternal(url)
    }
)
```

## UIKit

The UIKit product exposes `ReturningAIWidgetView`. Normal deallocation cleans up the session; call `dispose()` when ending it manually.

`RewardsViewController.swift`

```swift
let widgetView = ReturningAIWidgetView(
    configuration: configuration,
    embedTokenProvider: {
        try await backend.fetchReturningAIEmbedToken()
    }
)

containerView.addSubview(widgetView)

// When manually ending this widget surface:
widgetView.dispose()
```

## Session lifecycle

- Use `ReturningAIWidgetController` for reload, retry, theme, soft logout, session queries, and terminal invalidation.
- On host logout or account change, dispose the old UIKit view or replace the SwiftUI representable identity.
- A new user requires a new widget surface and a new embed-token provider.

Return to the [Mobile Widget SDK overview](https://docs.returning.ai/mobile-widget-sdk.md).
