---
title: "iOS seat map"
description: "Install the official SeatLayer iOS Swift package, render live seating charts in your app, create holds, and hand booking to a trusted server."
---

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

# iOS seat map

The official SeatLayer iOS seat map SDK adds an interactive seating chart and
seat picker to reserved-seating apps in Swift. The
[`seatlayer-ios` Swift package](https://github.com/seatlayer/seatlayer-ios)
provides a typed view, delegate, async commands, structured errors, and events
for live availability, seat selection, temporary holds, and best-available
seating on iOS 15 and later.

[Inspect the iOS source and example app](https://github.com/seatlayer/seatlayer-ios),
learn about the [SeatLayer reserved-seating platform](https://seatlayer.io/), or
preview the wider buyer experience in the
[browser seat-map demo](https://app.seatlayer.io/demo/play). The browser demo
is product proof, not an iOS application.

> **The app selects and holds; your server books**
>
> Never put a SeatLayer secret key in an iOS binary or WebView. Send the opaque
> hold id to your trusted backend, inspect the hold there, calculate the charge
> from server data, and book with a stable `bookingRef`.

## Install the Swift package

In Xcode, choose **File → Add Package Dependencies** and enter:

```text
https://github.com/seatlayer/seatlayer-ios.git
```

Or declare the dependency in a manifest:

```swift
dependencies: [
    .package(url: "https://github.com/seatlayer/seatlayer-ios.git", from: "0.2.0")
]
```

Add the `SeatLayer` product to your iOS target. The package supports iOS 15+
with Swift 5.9+.

## Render a seating chart

Create the view, set a delegate, and load your event. Every buyer action is an
`async throws` Swift call:

```swift
import SeatLayer

let map = SeatLayerView()
map.delegate = self

var config = SeatLayerConfiguration(event: "ev_your_event_key", currency: "USD")

let info = try await map.load(config)
if case .test = info.mode { showTestBadge() }   // books no real inventory

let hold = try await map.hold()
```

Give `SeatLayerView` an explicit height or make it full-screen. Do not place it
inside a `UIScrollView`, `List`, or SwiftUI `ScrollView` — the buyer canvas
owns pan and pinch gestures, and the SDK already disables the WebView
affordances that fight the canvas.

In SwiftUI, wrap the view in `UIViewRepresentable` and give it a definite
frame.

## Understand the hosted runtime boundary

`SeatLayerView` hosts the buyer experience in `WKWebView`. Production views
load the immutable, version-pinned mobile runtime from
`https://cdn.seatlayer.io`; application code stays in Swift and communicates
through typed commands, delegate events, payloads, and structured errors. The
API matches the web `SeatingChart` one-to-one, so iOS and web read as one
product.

This boundary gives the app one canonical HTTPS origin for origin-restricted
buyer sessions. Access tokens stay in memory and are never placed in page URLs
or emitted as application events.

For private channel inventory, provide a short-lived token from your backend:

```swift
config.buyerAccessTokenProvider = { context in
    try await buyerBackend.mintSeatLayerAccess(reason: context.reason)
}
```

## Select, hold, and hand off checkout

Keep the security boundary explicit:

- The iOS app selects seats and creates a temporary hold.
- Your backend inspects the hold and derives the amount to charge.
- Your payment and order workflow stays outside the WebView.
- Your backend books with a stable `bookingRef` so retries are safe.
- Expiry and inventory conflicts return buyers to a recoverable selection
  state.

Continue with [holds and checkout](/buyer-sdk/holds-and-checkout) before
connecting a production order flow.

## Commands and delegate events

Common commands include `hold`, `resumeHold`, `extendHold`, `release`,
`bestAvailable`, `getSelection`, `selectObjects`, `clearSelection`,
`getCurrentHold`, `setFloor`, `setViewMode`, `getViewMode`, `zoomIn`,
`zoomOut`, `zoomToFit`, and `destroy` — all `async throws`.

Events reach `SeatLayerViewDelegate`, which has a no-op default for every
method: `ready`, `selectionChanged`, selection validity changes,
buyer-access expiry, `holdChanged`, `holdRestored`, `holdExpired`, `gaClick`,
`seatHover`, `error`, and `didReceiveUnknownEvent`. Every bridged enum has an
`unknown(String)` case, so newer runtime values never crash an older app.

## iOS seat-map checklist

- Give the seat map a definite height or a full-screen view controller.
- Keep the view for one screen lifecycle; call `destroy` when finished.
- Preserve the hold id across checkout navigation or app suspension if your
  product promises restoration.
- Test rotation, safe areas, back navigation, suspension, and resume.
- Verify selection, hold, expiry, release, conflict, and booking with a test
  event.
- Smoke-test supported physical iPhones and iPads before rollout.

## Frequently asked questions

### Is this a native Swift seat map or a WebView?

Rendering runs in `WKWebView` on SeatLayer's immutable, version-pinned buyer
runtime, and application code never touches the web layer: commands, payloads,
errors, and events are all typed Swift.

### Does it work with SwiftUI?

Yes — wrap `SeatLayerView` in `UIViewRepresentable` and give it a definite
frame. Do not place it inside a SwiftUI `ScrollView`.

### How do temporary seat holds work?

Selecting seats creates a temporary hold that reserves inventory against
concurrent buyers for a limited window. The hold expires automatically if
checkout does not complete — `holdExpired` tells the app to return the buyer
to the map — and `extendHold` and `resumeHold` cover longer checkouts and app
restarts.

### Can I use my own payment provider?

Yes. SeatLayer never processes payment inside the seat map. The app hands the
hold id to your backend, and your backend charges through any payment provider
you already use before booking the hold.

### Can I evaluate the SDK without a SeatLayer account?

Yes. The repository's example app and test suite exercise the view, bridge,
and renderer against the bundled offline fixture. Use a test event when
validating live inventory, holds, expiry, and checkout.

### Does the iOS SDK include a 3D seating chart?

SeatLayer offers an [optional browser 3D seat-map experience](https://seatlayer.io/3d-seat-map/).
This page does not claim a released native iOS 3D contract; validate the
documented view modes and device support for your integration.

## Next steps

- [Run or inspect the iOS SDK source](https://github.com/seatlayer/seatlayer-ios)
- [Understand the SeatLayer platform](https://seatlayer.io/)
- [Preview the buyer seat map in a browser](https://app.seatlayer.io/demo/play)
- [Compare every mobile SDK](/buyer-sdk/mobile)
- [Connect holds to secure checkout](/buyer-sdk/holds-and-checkout)

Source: https://docs.seatlayer.io/buyer-sdk/ios/index.mdx
