API reference
The public surface of
ThunderID, as documented in its reference pages.SignInThe `SignIn` component renders a full app-native sign-in form. It drives the Flow Execution API loop automatically: initiating the flow, presenting the server-defined inputs and actions on each step, and completing when the user is authenticated. `SignIn` requires `.thunderIDProvider(config:)` in its ancestor view hierarchy.
applicationIdrequiredStringThe Application ID from your ThunderID application settings. Identifies which sign-in flow to execute.
onCompleteoptional(() -> Void)?Called when authentication completes successfully.
onErroroptional((String) -> Void)?Called with an error message when a flow step fails.
import SwiftUIimport ThunderIDSwiftUIstruct AuthView: View {var body: some View {SignIn(applicationId: "<your-application-id>").padding()}}
SignInButtonThe `SignInButton` component renders a pre-styled button that you can use to trigger your sign-in flow. It reads loading state from `ThunderIDState` and disables itself automatically while an operation is in progress. `SignInButton` requires `.thunderIDProvider(config:)` in its ancestor view hierarchy.
onTapoptional(() -> Void)?Called when the button is tapped. Use this to present a sign-in sheet or navigate to an auth view.
import SwiftUIimport ThunderIDSwiftUIstruct LandingView: View {var body: some View {SignInButton()}}
SignOutButtonThe `SignOutButton` component renders a pre-styled button that calls `ThunderIDClient.signOut()`, then calls `ThunderIDState.refresh()` to update the reactive auth state. It disables itself automatically while the sign-out operation is in progress. `SignOutButton` requires `.thunderIDProvider(config:)` in its ancestor view hierarchy.
onSignOutCompleteoptional(() -> Void)?Called after sign-out completes and `ThunderIDState` has been refreshed.
import SwiftUIimport ThunderIDSwiftUIstruct HomeView: View {var body: some View {VStack {Text("You are signed in.")SignOutButton()}}}
SignUpThe `SignUp` component renders a full app-native registration form. It drives the Flow Execution API registration loop automatically: initiating the flow, presenting the server-defined inputs and actions on each step, and completing when the user is registered and authenticated. `SignUp` requires `.thunderIDProvider(config:)` in its ancestor view hierarchy.
applicationIdrequiredStringThe Application ID from your ThunderID application settings. Identifies which registration flow to execute.
onCompleteoptional(() -> Void)?Called when registration completes successfully.
onErroroptional((String) -> Void)?Called with an error message when a flow step fails.
import SwiftUIimport ThunderIDSwiftUIstruct AuthView: View {@State private var showSignUp = falsevar body: some View {if showSignUp {SignUp(applicationId: "<your-application-id>").padding()} else {SignIn(applicationId: "<your-application-id>").padding()}}}
SignedInThe `SignedIn` component conditionally renders its content only when the user is authenticated. It reads the current sign-in state from `ThunderIDState` and displays protected UI for signed-in users, while rendering optional fallback content (or nothing) when the user is not authenticated. `SignedIn` requires `.thunderIDProvider(config:)` in its ancestor view hierarchy.
contentrequired@ViewBuilder () -> ContentThe view to render when the user is authenticated.
fallbackoptional@ViewBuilder () -> FallbackThe view to render when the user is not authenticated. Defaults to `EmptyView`.
import SwiftUIimport ThunderIDSwiftUIstruct ContentView: View {var body: some View {SignedIn {Text("You are signed in.")}}}
SignedOutThe `SignedOut` component conditionally renders its content only when the user is **not** authenticated. It reads the current sign-in state from `ThunderIDState` and displays content for unauthenticated users, while rendering optional fallback content (or nothing) when the user is signed in. `SignedOut` requires `.thunderIDProvider(config:)` in its ancestor view hierarchy.
contentrequired@ViewBuilder () -> ContentThe view to render when the user is not authenticated.
fallbackoptional@ViewBuilder () -> FallbackThe view to render when the user is authenticated. Defaults to `EmptyView`.
import SwiftUIimport ThunderIDSwiftUIstruct ContentView: View {var body: some View {SignedOut {Text("Please sign in to continue.")}}}
UserProfileThe `UserProfile` component renders an editable profile form. It loads the user's current profile from `/scim2/Me` when it appears, presents editable fields for `displayName` and `phoneNumbers`, and saves changes via `ThunderIDClient.updateUserProfile`. `UserProfile` requires `.thunderIDProvider(config:)` in its ancestor view hierarchy.
onSavedoptional(() -> Void)?Called after a successful profile save.
onErroroptional(() -> Void)?Called when a load or save operation fails.
import SwiftUIimport ThunderIDSwiftUIstruct ProfileSheet: View {@Environment(\.dismiss) var dismissvar body: some View {UserProfile {dismiss()}.padding()}}
ChangeCredentialThe `ChangeCredential` view lets a signed-in user set a new value for one of their own credentials. It validates against the user type schema (`GET /users/me/meta`) and posts the change via `ThunderIDClient.updateUserCredentials`. Defaults to `password`; set `attribute` for another credential, such as a PIN. Requires `.thunderIDProvider(config:)` in the view hierarchy. Collects only a new value and its confirmation, not the current one, since the write path doesn't verify it today.
attributeoptionalStringThe credential attribute this instance manages, any attribute the user type schema declares `credential: true` for. Defaults to `"password"`.
onSuccessoptional(() -> Void)?Called after the credential has been changed successfully.
import SwiftUIimport ThunderIDSwiftUIstruct SecuritySection: View {var body: some View {VStack(alignment: .leading) {Text("Security")ChangeCredential()}}}
Configuration`ThunderIDConfig` is the configuration struct passed to `ThunderIDClient.initialize(config:storage:)` and to the `.thunderIDProvider(config:)` view modifier.
baseUrlString**Required.** Your ThunderID instance URL. Must use HTTPS (e.g., `https://localhost:8090`).
clientIdString?The Client ID from your ThunderID application. Required for redirect-based authentication and token operations.
scopes[String]OAuth 2.0 scopes to request. Include `"profile"` and `"email"` to receive user identity claims.
afterSignInUrlString?The redirect URI to return to after sign-in. Must match an **Allowed Redirect URI** registered in the console.
afterSignOutUrlString?The redirect URI to return to after sign-out. Must match an **Allowed Post-Logout Redirect URI** in the console.
signInUrlString?Override the sign-in URL. Defaults to the ThunderID hosted sign-in page.
signUpUrlString?Override the sign-up URL.
clientSecretString?Client secret for confidential clients. Do not include this in a shipped iOS app.
signInOptions[String: Any]Additional query parameters appended to the authorization URL on sign-in.
signOutOptions[String: Any]Additional parameters sent with the sign-out request.
signUpOptions[String: Any]Additional parameters sent with the sign-up request.
applicationIdString?The Application ID used for app-native (embedded) sign-in flows via the Flow Execution API.
organizationHandleString?The organization handle for multi-tenant deployments.
tokenValidationTokenValidationConfigControls ID token validation behavior.
storageStorageAdapter?Custom token storage backend. Defaults to `KeychainStorageAdapter`.
instanceIdInt?Identifies the SDK instance when running multiple instances in one process.
import ThunderIDlet config = ThunderIDConfig(baseUrl: "https://localhost:8090",clientId: "<your-client-id>",scopes: ["openid", "profile", "email"],afterSignInUrl: "io.thunderid.b2c://callback",afterSignOutUrl: "io.thunderid.b2c://logout",applicationId: "<your-application-id>")
ThunderIDClient`ThunderIDClient` is the core authentication client in the `ThunderID` package. It manages the full authentication lifecycle: initialization, sign-in (both app-native and redirect-based), session, token management, and user profile operations. When you use the `ThunderIDSwiftUI` package, a `ThunderIDClient` instance is created and managed automatically. You can access it via `ThunderIDState.client` from any view.
import ThunderIDlet client = ThunderIDClient()try await client.initialize(config: ThunderIDConfig(baseUrl: "https://localhost:8090",clientId: "<your-client-id>",scopes: ["openid", "profile", "email"],afterSignInUrl: "io.thunderid.b2c://callback",afterSignOutUrl: "io.thunderid.b2c://logout"))
ThunderIDState`ThunderIDState` is the reactive authentication state object provided by the `ThunderIDSwiftUI` package. It is an `ObservableObject` that holds the current user, loading state, and initialization status, and exposes the underlying `ThunderIDClient` for direct API calls. `ThunderIDState` is injected into the SwiftUI environment by the `.thunderIDProvider(config:)` modifier. Any view in the hierarchy can read it using `@EnvironmentObject`.
import SwiftUIimport ThunderIDSwiftUI@mainstruct MyApp: App {var body: some Scene {WindowGroup {ContentView().thunderIDProvider(config: ThunderIDConfig(baseUrl: "https://localhost:8090",clientId: "<your-client-id>",afterSignInUrl: "io.thunderid.b2c://callback",afterSignOutUrl: "io.thunderid.b2c://logout"))}}}