Skip to main content
While SeamAccessView is the fastest way to integrate mobile keys, many apps need more control over layout, navigation, or data flow. SeamComponents supports full customization through composable building blocks and protocol-based dependency injection.

Building Blocks

SeamComponents exports a set of reusable, domain-specific SwiftUI views: Each component works with a single service wrapper conforming to SeamServiceProtocol, so you can inject live or mock implementations as needed.

Example: Custom Key List and Unlock Flow

Create and own a SeamCredentialsViewModel, then pass it to the credential views. The coordinator views handle selection, navigation, refresh, and empty state automatically.
Use the coordinator views (SeamCredentialsGridView, SeamCredentialsTableView) for a full-featured experience — empty states, selection, refresh, and unlock presentation are all handled for you.

Dependency Injection and Mocks

SeamComponents uses a single wrapper ObservableObject API:

Live Usage

Mock Usage (Tests and Previews)

This design keeps your UI and business logic independent of concrete SDK types, while remaining iOS 16-friendly.

Custom Styling and Extensibility

All views are built with SwiftUI best practices — system fonts, SF Symbols, and color styles. You can:
  • Override styles using environment modifiers.
  • Add your own accessibility labels and localization.
  • Compose SeamComponents with your own views and navigation.
  • Use SeamAccessCredentialErrorStyle to override error/status badge appearance, icons, and messaging in key card and unlock views.
See Customizing Appearance for the full theming API.

Handling Unlock Events and Errors

The unlock stream emits SeamAccessUnlockEvent values and never fails. Available events: Subscribe to these events to show custom notifications, present modals, or log analytics.

Credential Errors and Presentation

Per-credential issues surface via each credential’s errors: [SeamCredentialError] array. Use SeamAccessCredentialErrorStyle to present badges, messages, and actions consistently across key cards and unlock views. Rendering an error badge on a key card:
Offering a corrective action:
The errors array is ordered by severity. Show the first item as the primary badge on a key card, and reveal details or actions on tap.
If unlock(using:) throws .credentialErrors([...]), present the top error using your style and avoid starting the unlock until it is resolved.
Credential error types:
  • awaitingLocalCredential — Waiting for a local credential to become available.
  • expired — The credential has expired and cannot be used.
  • userInteractionRequired(action) — The user must perform a specific action.
  • contactSeamSupport — Configuration error requiring developer attention.
  • unsupportedDevice — The current device is not supported for this credential.
  • unknown — An unclassified or unexpected issue occurred.
Possible userInteractionRequired actions:
  • completeOtpAuthorization(otpUrl:) — Open the provided URL to complete OTP authorization.
  • enableInternet — Prompt the user to enable internet connectivity.
  • enableBluetooth — Prompt the user to turn on Bluetooth.
  • grantBluetoothPermission — Direct the user to grant Bluetooth permission.
  • appRestartRequired — Ask the user to restart the app.

See Also