iOS Representations#
The Curity HAAPI iOS SDK delivers every HAAPI response as a typed Swift value. HaapiResult is the top-level enum returned by HaapiManager.start, submitForm, and followLink; its .representation case carries a HaapiRepresentation whose concrete type tells you which step the server is asking the client to render.
The same model hierarchy exists on Android and React Native — see Android Representations and React Native Representations for the per-platform shape. This page is the iOS narrative reference.
SDK-thrown errors are inside HaapiResult. Network failures, attestation failures, and other framework errors arrive as the third enum case, .error(Error). Match on it the same way you match on .representation and .problem. See Error Handling for the typed HaapiError hierarchy.
Response Hierarchy#
HaapiResult is a Swift enum with three cases. Every call to HaapiManager.start, submitForm, or followLink resolves to one of them:
| Case | When it surfaces | Carries |
|---|---|---|
.representation(HaapiRepresentation) | The flow continues with another step | A concrete struct conforming to HaapiRepresentation (or ClientOperationStep) |
.problem(ProblemRepresentation) | The server rejected the request (RFC 7807) | A type conforming to Problem — InvalidInputProblem, AuthorizationProblem, or the base Problem |
.error(Error) | Framework / transport failure | An Error value — cast to HaapiError for the typed hierarchy |
Match on the enum case first, then narrow further by casting the associated value to the concrete step or problem type.
Step Types#
HaapiRepresentation is a Swift protocol implemented by 14 concrete structs. Two distinct protocols capture the model — HaapiRepresentation for renderable steps and ClientOperationStep for steps that delegate to an external operation.
Common fields#
Every step exposes these base fields through the protocol:
| Field | Type | Description |
|---|---|---|
type | RepresentationType | HAAPI representation type (8 values) |
metadata | Metadata? | Template area and view name |
actions | [Action] | Available actions for this step |
links | [Link] | Navigation links (e.g., “forgot password”) |
messages | [UserMessage] | User-facing messages to display |
properties | Properties? | Step-specific properties |
The 14 step types#
Grouped by purpose:
| Group | Concrete type | Extra fields |
|---|---|---|
| Interactive | AuthenticatorSelectorStep | title: Message, authenticators: [AuthenticatorOption] |
InteractiveFormStep | (form actions inside actions) | |
UserConsentStep | — | |
| Flow control | RedirectionStep | redirectAction: Action |
PollingStep | mainAction, cancelAction?, pollingProperties | |
ContinueSameStep | — | |
| OAuth | OAuthAuthorizationResponseStep | oauthAuthorizationResponseProperties (carries code) |
Client operation (conform to ClientOperationStep) | ExternalBrowserClientOperationStep | — |
BankIdClientOperationStep | activationLink? | |
EncapClientOperationStep | — | |
WebAuthnRegistrationClientOperationStep | — | |
WebAuthnAuthenticationClientOperationStep | — | |
GenericClientOperationStep | — | |
| Fallback | GenericRepresentationStep | properties? |
Switching on the result#
import IdsvrHaapiSdk
haapiManager.start { result in
switch result {
case .representation(let representation):
handleRepresentation(representation)
case .problem(let problem):
handleProblem(problem)
case .error(let error):
// Cast to HaapiError for the typed hierarchy — see Error Handling.
handleError(error)
}
}
private func handleRepresentation(_ representation: HaapiRepresentation) {
switch representation {
case let step as AuthenticatorSelectorStep:
// step.title.literal, step.authenticators
// Each AuthenticatorOption carries an Action.Form for selection.
break
case let step as InteractiveFormStep:
// step.actions includes form actions; render their fields as a UIKit form.
break
case let step as PollingStep:
// step.pollingProperties.status, step.mainAction, step.cancelAction
break
case let step as OAuthAuthorizationResponseStep:
// Flow complete — extract the authorization code.
let code = step.oauthAuthorizationResponseProperties.code
break
case let step as ClientOperationStep:
// Delegate to the platform (BankID, WebAuthn, external browser, …)
break
default:
// GenericRepresentationStep, ContinueSameStep, UserConsentStep, RedirectionStep.
break
}
}
Actions#
Actions represent operations the user can perform. They live under the Action enum:
| Case | actionType | Carries | When to use |
|---|---|---|---|
Action.form(FormAction) | .form | FormActionModel | The most common action — render fields, submit values |
Action.selector(SelectorAction) | .selector | [Action] (nested options) | Server provides a choice (e.g., device selector); each option is itself an Action |
Action.clientOperation(ClientOperationAction) | .clientOperation | A ClientOperationActionModel | External handling required (BankID, WebAuthn, browser launch) |
Every action also carries:
| Field | Type | Description |
|---|---|---|
kind | ActionKind | Semantic meaning: .login, .cancel, .redirect, .poll, etc. (17 values) |
title | Message? | Display title for buttons / labels |
FormAction#
Submitting a form is the SDK’s primary write operation:
let formAction: FormActionModel = …
let parameters: [String: Any] = [
formAction.fields[0].name: "user@example.com",
formAction.fields[1].name: "secret"
]
haapiManager.submitForm(formAction, parameters: parameters) { result in
handleResult(result)
}
submitForm’s parameters accept any JSON-serialisable value for non-GET methods; GET form actions require [String: String]. See HAAPI Flow for the full parameter-type semantics across platforms.
The FormActionModel carries:
| Field | Type | Description |
|---|---|---|
fields | [FormField] | Form fields to render |
method | String | HTTP method (e.g., "POST") |
href | String | Target URI |
actionTitle | Message? | Submit button text |
ClientOperationAction#
Six sub-types, each with its own model fields: ExternalBrowser, BankId, Encap, WebAuthnRegistration, WebAuthnAuthentication, Generic. Each model includes continueActions and errorActions arrays for post-operation flow.
Form Fields#
FormField is a Swift enum with 7 cases:
Common fields#
| Field | Type | Description |
|---|---|---|
name | String | Parameter key for submission |
value | String? | Current / default value |
label | Message? | Display label |
placeholder | Message? | Placeholder text |
isRequired | Bool | Whether the field is required |
Rendering guide#
FormField case | UIKit element | Notes |
|---|---|---|
.hidden | none | Include value in submit params automatically — don’t render |
.text | UITextField | Inspect kind for keyboard type (.email, .tel, etc.) |
.username | UITextField | autocapitalizationType = .none |
.password | UITextField | isSecureTextEntry = true |
.select | UIPickerView or UIButton set | Render options as choices |
.checkbox | UISwitch | Respect readOnly flag |
.context | none | Hidden context data (e.g., WebAuthn challenge) — don’t render |
Problems#
Problem responses follow RFC 7807. iOS uses a Problem protocol with three concrete types:
| Type | problemType | Extra fields |
|---|---|---|
Problem (base) | base value | (base only) |
InvalidInputProblem | .invalidInput | invalidFields: [InvalidField] (each: name, reason?, detail: Message), errorDescription? |
AuthorizationProblem | .authorization | error, errorDescription? |
InvalidInputProblem.invalidFields is the right hook for showing field-level validation errors inline in your form.
Token Responses#
OAuthTokenManager.fetchAccessToken, refreshAccessToken, and revokeRefreshToken return a TokenResponse enum. Match its cases:
| Case | Fields |
|---|---|
.successfulToken(SuccessfulTokenResponse) | accessToken, tokenType?, scope?, expiresIn, refreshToken?, idToken? |
.errorToken(ErrorTokenResponse) | error, errorDescription?, errorUri? |
.error(Error) | Framework / transport error |
See OAuthTokenManager for the full lifecycle, and Error Handling for the difference between RFC-6749 OAuth errors (values) and framework errors.
Links#
Each Link carries:
| Field | Type | Description |
|---|---|---|
href | String | Target URI |
rel | String | Relationship type (e.g., forgot-password) |
title | Message? | Display text |
Render link sets alongside the main form — typically as secondary buttons or text links. Submit a link via haapiManager.followLink(link) to navigate.
Related: HAAPI Flow · OAuthTokenManager · Error Handling · iOS SDK · iOS Reference (DocC for the full type signatures)