> ## Documentation Index
> Fetch the complete documentation index at: https://docs.uplink.build/llms.txt
> Use this file to discover all available pages before exploring further.

# iOS SDK

> Integrate the Uplink native SDK into your iOS app

The Uplink iOS SDK embeds a worker inside your iOS app, making the device controllable from server-side code written with the [JavaScript SDK](/api-reference/overview). Use it when you want Uplink automation to run inside your own branded app.

<Info>
  **Key concepts:**

  * **Device**: A physical iOS device running your app
  * **Worker**: A worker created by the Uplink SDK inside your app (one app can create multiple workers)
  * **Session**: An authenticated connection that pairs your worker with a JavaScript SDK client
</Info>

## Requirements

* iOS 15.1 or later
* Swift 6.0 or later
* Xcode 16 or later

## Installation

The iOS SDK is distributed via Swift Package Manager.

<Steps>
  <Step title="Add the package">
    In Xcode, go to **File → Add Package Dependencies…** and enter:

    ```
    https://github.com/uplink-code/uplink-ios-public
    ```
  </Step>

  <Step title="Select the UplinkIOS product">
    Choose the `UplinkIOS` library product and add it to your app target.
  </Step>

  <Step title="Import the module">
    ```swift theme={null}
    import UplinkIOS
    ```
  </Step>
</Steps>

If you manage dependencies with a `Package.swift` file:

```swift theme={null}
dependencies: [
    .package(url: "https://github.com/uplink-code/uplink-ios-public", from: "0.0.0-alpha10")
],
targets: [
    .target(
        name: "YourApp",
        dependencies: [
            .product(name: "UplinkIOS", package: "uplink-ios-public")
        ]
    )
]
```

## Quick example

```swift theme={null}
import UIKit
import UplinkIOS

@MainActor
func startUplink(in viewController: UIViewController, session sessionUrl: String) async throws {
    let uplink = Uplink()
    let worker = uplink.worker(controller: viewController)

    try await worker.connect(session: sessionUrl)

    Task {
        try await worker.accept()
    }
}
```

## Initialization

Create a single `Uplink` instance in your app and use it to spawn workers.

```swift theme={null}
let uplink = Uplink()
```

### `uplink.worker(controller:)`

Creates a new `Worker` bound to a `UIViewController`. The SDK uses the controller to host its `WKWebView`, so pass the view controller that should own the SDK's browser surface (typically the one currently on screen).

```swift theme={null}
func worker(controller: UIViewController) -> Worker
```

**Parameters:**

* `controller`: The `UIViewController` that will host the SDK's web view

**Returns:** A new `Worker` ready to connect to a session

```swift theme={null}
let worker = uplink.worker(controller: self)
```

<Tip>
  Keep a strong reference to the `Worker` for as long as the connection is active. If the worker is deallocated, the session will close.
</Tip>

## Obtaining a session

Your backend creates a session using the JavaScript SDK's `uplink.session()` and delivers the resulting session URL to the app. How you deliver it — a backend API response, a universal link, a QR code — is up to you.

```swift theme={null}
let sessionUrl: String = // from your backend, deep link, or QR code
```

See [Sessions](/sessions) for how sessions are created on the server side.

## Connecting and accepting

### `worker.connect(session:)`

Connects the worker to an Uplink session.

```swift theme={null}
func connect(session: String) async throws
```

**Parameters:**

* `session`: The session URL provided by your backend

```swift theme={null}
try await worker.connect(session: sessionUrl)
```

### `worker.accept()`

Begins accepting commands from the JavaScript SDK client. `accept()` suspends until the worker closes, so call it from a `Task` if you want the rest of your app to continue running.

```swift theme={null}
func accept() async throws
```

```swift theme={null}
Task {
    try await worker.accept()
}
```

## Cleanup

### `worker.close()`

Closes the worker and releases its resources.

```swift theme={null}
func close() async throws
```

```swift theme={null}
try await worker.close()
```

<Warning>
  Closing a worker ends its session. Any browsers the JavaScript SDK has launched on the worker will be terminated.
</Warning>

## Complete example

A minimal `UIViewController` that starts an Uplink worker when it appears:

```swift theme={null}
import UIKit
import UplinkIOS

final class UplinkViewController: UIViewController {
    private let uplink = Uplink()
    private var worker: Worker?

    func start(sessionUrl: String) {
        Task { @MainActor in
            let worker = uplink.worker(controller: self)
            self.worker = worker

            do {
                try await worker.connect(session: sessionUrl)
                try await worker.accept()
            } catch {
                print("Uplink worker ended: \(error)")
            }
        }
    }

    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)

        Task { [worker] in
            try? await worker?.close()
        }
    }
}
```

## Related

<CardGroup cols={2}>
  <Card title="Android SDK" icon="android" href="/api-reference/android">
    Integrate Uplink into your Android app
  </Card>

  <Card title="JavaScript SDK" icon="plug" href="/api-reference/overview">
    Control your worker from server-side code
  </Card>

  <Card title="Sessions" icon="key" href="/sessions">
    How sessions are created and secured
  </Card>

  <Card title="Core concepts" icon="book" href="/fundamentals/core-concepts">
    Architecture overview
  </Card>
</CardGroup>
