> For the complete documentation index, see [llms.txt](https://docs.onside.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.onside.io/sdk/customization/delegate.md).

# The Onside Delegate

Customize OnsideKit with OnsideDelegate — host window scene, window level, per-screen theme override, login routing, and a pre-login region hint.

`OnsideDelegate` lets you tune how OnsideKit presents its screens and routes login. Every method has a default implementation, so implement only the ones you need.

```swift
protocol OnsideDelegate: AnyObject {
    @MainActor func onside(hostWindowSceneForScreen screen: OnsideScreen) -> UIWindowScene?
    @MainActor func onside(uiWindowLevelOverrideForScreen screen: OnsideScreen) -> UIWindow.Level?
    @MainActor func onside(uiThemeOverrideForScreen screen: OnsideScreen) -> OnsideUIThemeMode?
    @MainActor func onsideLoginMethod() -> OnsideLoginMethod
    @MainActor func onsideDefaultCountryCodeAssumption() -> String?
    @MainActor func onsideShouldOverrideHostSupportedInterfaceOrientations() -> Bool
}
```

Assign your delegate (keep a strong reference — it's held weakly), typically at launch:

```swift
@main
final class AppDelegate: UIResponder, UIApplicationDelegate, OnsideDelegate {
    func application(
        _ application: UIApplication,
        didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
    ) -> Bool {
        Onside.initialize()
        Onside.delegate = self
        return true
    }
}
```

## OnsideScreen

Several delegate methods receive the screen OnsideKit is about to present:

```swift
enum OnsideScreen {
    case login                   // the user authentication screen
    case paymentMethodsManager   // the saved-cards management screen
    case profileInfoFulfillment  // a step that collects/confirms profile info (e.g. region) during a purchase
    case purchase                // the purchase flow
    case externalAccountNotification // post-purchase receipt reminder for an external account
}
```

## Host window scene

```swift
func onside(hostWindowSceneForScreen screen: OnsideScreen) -> UIWindowScene?
```

OnsideKit presents each screen in its own `OnsideSDKWindow` (a `UIWindow` subclass), created in the scene this method returns — useful in multi-window apps. If you return `nil` (the default), OnsideKit picks a connected scene itself, preferring a `.foregroundActive` one, then `.foregroundInactive`, then any connected window scene.

```swift
func onside(hostWindowSceneForScreen screen: OnsideScreen) -> UIWindowScene? {
    return preferredScene   // or nil to use the default
}
```

{% hint style="warning" %}
If no connected window scene is available, OnsideKit cannot present its UI and the screen is not shown.
{% endhint %}

## Window level

```swift
func onside(uiWindowLevelOverrideForScreen screen: OnsideScreen) -> UIWindow.Level?
```

Set the `windowLevel` of the window OnsideKit presents the screen in. Return `nil` (the default) to let OnsideKit choose it, which is what most apps want:

* If the scene has no visible window above `UIWindow.Level.normal`, the SDK window stays at `.normal` — the behaviour apps have always had.
* Otherwise the SDK window is placed one level above the topmost visible window in the scene, so its UI is not covered by your elevated windows.
* The automatic level never goes above `UIWindow.Level.alert - 1`, leaving system alerts and the keyboard on top. Windows far above the alert level (system-owned ones, such as the keyboard window) are ignored when picking the level.

Return an explicit level to take over — for example to keep the SDK **below** a window of yours that must always stay on top:

```swift
func onside(uiWindowLevelOverrideForScreen screen: OnsideScreen) -> UIWindow.Level? {
    screen == .purchase ? .normal : nil
}
```

An explicit level is applied as-is, without the automatic elevation, so it is also the way to place the SDK window above a window of yours sitting at `UIWindow.Level.alert` or higher.

{% hint style="info" %}
The level is resolved once, when the screen is presented. If your app raises a higher window *while* an OnsideKit screen is on screen, that window will cover it — return an explicit level in that case.
{% endhint %}

When the screen is dismissed, OnsideKit removes its window. If it still holds key-window status, it restores the previous eligible host window or another visible eligible window in the same scene. It does not take focus back from a window that has already become key.

## Per-screen theme override

```swift
func onside(uiThemeOverrideForScreen screen: OnsideScreen) -> OnsideUIThemeMode?
```

Force a theme for a specific screen, overriding the [global theme](/sdk/customization/appearance.md) and the system appearance:

* `.light` / `.dark` — force that theme
* `.auto` — follow the system setting
* `nil` (default) — no override; fall back to the global theme, then the system theme

```swift
func onside(uiThemeOverrideForScreen screen: OnsideScreen) -> OnsideUIThemeMode? {
    screen == .login ? .dark : nil
}
```

## Login method

```swift
func onsideLoginMethod() -> OnsideLoginMethod { .local }
```

* `.auto` (default) — try the Onside store app when available and a callback scheme is configured; otherwise use the SDK phone login.
* `.local` — use the SDK phone login without the store-app handoff.

An assigned `Onside.externalLoginDelegate` takes priority. This method selects the regular login route when external login is disabled or falls back. See [External Login](/sdk/core-concepts/external-login.md).

## Orientation and window resizing

SDK screens use portrait orientation by default, including in landscape-only host apps. OnsideKit applies its orientation override to active SDK windows and restores the host window’s supported orientations when its UI closes. Its sheets and navigation layouts adapt when the scene is resized; on iPadOS 26, the SDK window also accounts for the system window controls.

```swift
func onsideShouldOverrideHostSupportedInterfaceOrientations() -> Bool { false }
```

Return `false` only if your app handles the orientation policy itself. In that case, allow portrait for SDK windows in your host orientation callback:

```swift
func application(
    _ application: UIApplication,
    supportedInterfaceOrientationsFor window: UIWindow?
) -> UIInterfaceOrientationMask {
    if window is OnsideSDKWindow { return .portrait }
    return .landscape // Replace with your host app's supported orientations.
}
```

`OnsideSDKWindow` is created and managed by the SDK; you do not create it yourself. Opting out does not select a landscape SDK layout. If the host excludes portrait, the SDK uses the host’s allowed orientations to avoid an empty orientation mask.

## Pre-login region hint

```swift
func onsideDefaultCountryCodeAssumption() -> String?
```

Provide an ISO 3166-1 alpha-2 country code (e.g. `"US"`, `"DE"`) to use as the region **before** the user logs in, improving logged-out pricing and availability. Return `nil` (default) to use the device region. Once the user logs in, the account's region is used and this hint is ignored. See [Regions & Storefronts](/sdk/products-and-subscriptions/regions-and-storefronts.md).


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.onside.io/sdk/customization/delegate.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
