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

# Iframe Integration

> Embed a run.cloud iOS simulator session and handle iOS simulator postMessage events.

# Iframe Integration

`run-cloud ios create` returns a signed `url` that can be opened directly or
embedded in an iframe.

```tsx theme={null}
<iframe
  title="run.cloud iOS simulator"
  src={session.url}
  allow="clipboard-read; clipboard-write"
  style={{ width: 390, height: 844, border: 0 }}
/>
```

Treat the URL as a secret. It is scoped to one user and one run.cloud session.

## Session timeout

Run.cloud sessions do not auto-close on inactivity unless requested:

```bash theme={null}
run-cloud ios create --inactivity-timeout 60s --json
run-cloud ios create --inactivity-timeout none --json
```

When enabled, the inactivity clock starts after the simulator is ready. Pointer,
touch, wheel, and keyboard input inside the iframe reset the timer. Watching the
stream without interacting does not reset it.

The last 10 seconds are shown as an overlay inside the iframe. When the timer
expires, the iOS simulator releases the lease and the iframe posts:

```ts theme={null}
{
  type: "ios-simulator:session-ended",
  device: string,
  reason: "inactive-timeout"
}
```

## Parent window messages

Listen for messages from the iframe and verify `event.source` before acting on
them.

```ts theme={null}
const iframe = document.querySelector<HTMLIFrameElement>("#run-cloud-ios");

window.addEventListener("message", (event) => {
  if (event.source !== iframe?.contentWindow) return;
  const data = event.data;
  if (!data || typeof data !== "object") return;

  if (data.type === "ios-simulator:status") {
    console.log({
      streaming: data.streaming === true,
      appLaunched: data.appLaunched === true,
      reactNative: data.reactNative === true,
      bundleId: typeof data.bundleId === "string" ? data.bundleId : null,
    });
  }

  if (data.type === "ios-simulator:auth-error") {
    // The signed URL or iframe cookie is invalid or expired.
  }

  if (
    data.type === "ios-simulator:session-ended" ||
    data.type === "ios-simulator:session-restart-requested"
  ) {
    // Hide the old iframe and create a fresh run.cloud session.
  }
});
```

## Message reference

| Message                                   | Direction        | Meaning                                                           |
| ----------------------------------------- | ---------------- | ----------------------------------------------------------------- |
| `ios-simulator:status`                    | iframe to parent | Stream and app readiness changed.                                 |
| `ios-simulator:auth-error`                | iframe to parent | The embed token or session cookie was rejected.                   |
| `ios-simulator:session-ended`             | iframe to parent | The session ended, usually due to inactivity or explicit release. |
| `ios-simulator:session-restart-requested` | iframe to parent | User clicked `Start app again`; create a new run.cloud session.   |
| `ios-simulator:command`                   | parent to iframe | Optional command channel for supported controls.                  |

## Commands

Send commands with `postMessage` to the iframe content window:

```ts theme={null}
iframe.contentWindow?.postMessage(
  { type: "ios-simulator:command", command: "reload" },
  "*",
);
```

Supported commands:

| Command               | Effect                                                       |
| --------------------- | ------------------------------------------------------------ |
| `reload`              | Reload the React Native app.                                 |
| `home`                | Press the simulator Home button.                             |
| `rotate`              | Rotate the simulator. Pass `direction: "left"` or `"right"`. |
| `screenshot`          | Ask the iframe to take a screenshot.                         |
| `toggleAccessibility` | Toggle the accessibility inspector.                          |

For control outside the browser, prefer CLI/API commands such as
`run-cloud ios open-url`.
