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

# Hello Journey

> A minimal SwiftUI app that loads a GBG GO journey.

A minimal integration that loads a web-based identity journey inside a native iOS app. This example compiles and runs as a standalone SwiftUI app.

## What This Example Demonstrates

* Initializing a `BridgeHost` with typed capability slots
* Declaring document capture support via handler assignment
* Displaying a journey using `BridgeWebView`
* Observing bridge errors

## Complete Source

```swift theme={null}
import GBGBridge
import SwiftUI

// MARK: - App Entry Point

@main
struct HelloJourneyApp: App {
    var body: some Scene {
        WindowGroup {
            JourneyView()
        }
    }
}

// MARK: - Journey View

struct JourneyView: View {
    // 1. Create the bridge host
    @StateObject private var host = BridgeHost(hostVersion: "1.0.0")

    // 2. Set the journey URL
    private let journeyURL = URL(string: "https://journey.example.com")!

    var body: some View {
        NavigationStack {
            VStack(spacing: 0) {
                // 3. Embed the bridge-connected WebView
                BridgeWebView(url: journeyURL, host: host)

                // 4. Show errors if any
                if let error = host.lastError {
                    ErrorBanner(message: error) {
                        host.clearError()
                    }
                }
            }
            .navigationTitle("Identity Verification")
            .navigationBarTitleDisplayMode(.inline)
            .onAppear {
                // 5. Declare document capture support by setting a handler
                host.documentCapture.handler = { [weak host] request in
                    guard let host else { return .cancelled(reason: "Host deallocated") }
                    return await host.documentCapture.awaitCompletion()
                }

                // 6. Detect and report camera permission state
                let camera = CameraDetector.check()
                host.documentCapture.permissionState = camera.permissionState
            }
        }
    }
}

// MARK: - Error Banner

struct ErrorBanner: View {
    let message: String
    let onDismiss: () -> Void

    var body: some View {
        HStack {
            Image(systemName: "exclamationmark.triangle.fill")
                .foregroundColor(.white)
            Text(message)
                .font(.caption)
                .foregroundColor(.white)
                .lineLimit(2)
            Spacer()
            Button(action: onDismiss) {
                Image(systemName: "xmark.circle.fill")
                    .foregroundColor(.white.opacity(0.7))
            }
        }
        .padding(.horizontal)
        .padding(.vertical, 8)
        .background(Color.red)
    }
}
```

## How It Works

1. **`BridgeHost(hostVersion:)`** creates a host with typed capability slots. No separate configuration dictionary is needed.

2. **Setting a handler** on `documentCapture` declares the capability as supported. The handler uses `awaitCompletion()` to suspend until the UI layer calls `complete()`.

3. **`CameraDetector.check()`** detects camera hardware and permission state. The `permissionState` is included in capability query responses.

4. **`BridgeWebView`** creates a `WKWebView`, injects the bootstrap script, registers the message handler, attaches the WebView to the host, and loads the journey URL.

5. **Error observation** — `host.lastError` is `@Published`, so the error banner appears and disappears reactively.

## What Happens at Runtime

```
1. App launches -> JourneyView renders
2. BridgeWebView creates and configures WKWebView
3. Bootstrap script injected (window.GBGBridge namespace created)
4. Journey URL loads, handler set on documentCapture slot
5. Web journey sends: capability.query request
6. Built-in handler responds: { environment: "ios", capabilities: { camera.document: { supported: true, permissionState: "granted" } } }
7. Web journey adapts its flow based on available capabilities and permissions
```

## Required Info.plist Entries

For this minimal example, no special Info.plist entries are needed beyond the defaults. If your journey URL uses HTTP during development, add:

```xml theme={null}
<key>NSAppTransportSecurity</key>
<dict>
    <key>NSAllowsLocalNetworking</key>
    <true/>
</dict>
```

## Next Steps

* [Two-Way Communication](/docs/go-v2/developer-integration/sdks/ios/examples/two-way-communication) — Send events and handle requests
* [Advanced Integration](/docs/go-v2/developer-integration/sdks/ios/examples/advanced-integration) — Custom handlers, lifecycle, and error handling
