Skip to main content
A production-style integration demonstrating custom configuration, lifecycle management, error handling, capability negotiation, and graceful degradation for environment-sensitive features like NFC.

What this example demonstrates

  • Typed capability slots for document capture with CameraDetector permission state
  • Custom capability registration for NFC
  • Runtime capability detection with pre-launch validation
  • CaptureResult-based response encoding (no manual JSONValue dictionaries)
  • Lifecycle management (background/foreground events)
  • Delegate-based message observation and routing
  • Graceful degradation for unsupported capabilities

Complete source

The full app below is a single SwiftUI target that demonstrates pre-launch capability validation, typed slots for document capture, custom NFC capability registration, lifecycle event forwarding, and delegate-based message observation. Read through the section markers (// MARK: -) to navigate; each block is the production-style version of a pattern shown elsewhere in the docs.

Architecture overview

Key patterns demonstrated

Pre-launch capability validation

Before starting the journey, the launcher checks whether all required capabilities are available:
This prevents users from starting a journey that will fail partway through due to missing hardware.

Lifecycle events

The app sends events when entering background and returning to foreground. The web journey can use these to pause/resume timers, save state, or handle session timeouts.

Permission state with CameraDetector

CameraDetector.check() detects hardware and permission status. The result is assigned to the typed slot’s permissionState, which is automatically included in capability query responses:
The web journey can now check permissionState before attempting capture and prompt the user to grant access if needed.

Typed Slots vs Custom Capabilities

This example demonstrates both patterns side by side:
  • Document capture uses a typed slot (host.documentCapture) — the SDK handles result encoding and busy rejection automatically.
  • NFC uses registerCustomCapability() — the handler receives a BridgeResponder and builds the response manually.

Graceful Degradation

NFC is detected at runtime. If not available, the launcher shows a warning, and the custom capability handler responds with .unsupported if somehow called.

Running this example

To run the example end-to-end, follow these setup steps:
  1. Add GBGBridge via SPM.
  2. Add to Info.plist:
  3. For NFC: Add the Near Field Communication Tag Reading capability.
  4. Update journeyURL to your web journey endpoint.
  5. Build and run.

Next steps