Get started
The packages, the prerequisites and the integration steps of the Folio SDK on iOS, Android and the web, with a minimal app per platform.
Preview
This page describes a pre-release version of the SDK. Names, versions and APIs on this page can change before the release.
This page takes you from an empty app to a first identity verification. It lists what you install on each platform, what you need before you start and the steps in their order. Each step links to the page that describes it in full.
Packages
| Platform | Packages | Interface |
|---|---|---|
| iOS | Swift package FolioSDK with the products FolioSDK, FolioInquiryUI and FolioSDKBinary. | Swift and SwiftUI (UIKit through UIHostingController) |
| Android | id.folio:sdk, which pulls in id.folio:sdk-native and the capture engine of the selfie step. | Kotlin, Jetpack Compose |
| Web | npm package @folio/sdk, which brings the capture engine of the selfie step as a dependency. | TypeScript, React |
Every package holds the same SDK core and the ready-made inquiry UI of its platform. The type names
are the same on every platform: FolioSdk, FolioSdkConfig, InquiryStore, InquiryEntry,
InquiryLifecycle and so on. Platforms lists the platform versions and what each
platform supports.
A web page that does not bundle the SDK can run the inquiry with one script tag instead. See Inquiry embed.
Before you start
- Access to the packages. Folio gives you access to the package repository of each platform
you build for. The setup guides write their addresses as
<ios-package-repository-url>,<android-maven-repository-url>and<web-package-url>, and the release version as<version>. - A supported platform version. iOS 15 or later with Xcode 15 or later. Android
minSdk23 or later with Java 17. On the web, React 18 or 19 and a bundler that serves ES modules. See Platforms. - An organization. Folio assigns it to your integration. The runtime configuration takes it
as
organization, which must be non-empty and contain only lowercase letters, digits and hyphens. Your app's identifier, version and build come from the platform. See Configuration. - A backend that creates inquiries. The SDK never creates an inquiry. Your backend creates each inquiry and passes the launch code it receives to your app. The launch code is opaque and single-use: the first exchange consumes it, so pass a fresh one for each inquiry, and keep the credentials your backend uses with Folio out of your app.
Integration steps
- Install the packages. Add the packages of your platform from the repository Folio gives you: iOS, Android or web.
- Configure the platform.
- iOS: configure your app for the camera, NFC, photos and files as the inquiries you run need. See iOS setup.
- Android: call
XPlatform.init(id.folio.sdk.platform.XPlatform) once per process, fromonCreateof yourApplicationsubclass. See Android setup. - Web: serve the WebAssembly module and its manifest, load it with
initializeFolioWasm, forward the/apipath and/.well-known/jwks.jsonof your origin to Folio, import the PlexUI and inquiry stylesheets and serve the illustrations and animations the package ships. See Web setup.
- Write an identity record mapper. When a government ID verification succeeds, the SDK calls
your
IdentityRecordMapperand saves theRecordContentit returns in the vault. The payload is your own JSON document. See Identity records for a complete mapper on each platform; the samples below use thatSavedIdentityMapper. - Create the runtime. Create one
FolioSdkwithFolioSdk.create:create(config:mapper:)in Swift,create(config, mapper)in Kotlin and TypeScript. The call completes when the runtime is ready: it has restored the stored session, or started a new one. On Android,rememberFolioSdk(config, mapper)does this in Compose. See Runtime and stores and Configuration. - Mount stores. The runtime returns no data. Mount the stores you need on it, render their
state and send them actions:
SessionStore,AuthStore,VaultStore,InquiryStore,MrtdStore,LogsStore,FolioDocumentListStoreandFolioDocumentStore.FolioSDKProviderhands the runtime to your views on every platform; on Android theremember<Name>Store()composables and in React theuse<Name>Store()hooks mount a store for the lifetime of a view. See Providers. - Run an inquiry. Pass the launch code from your backend to the ready-made inquiry UI as the
start entry:
.start(launchCode:)in Swift,InquiryEntry.Start(launchCode)in Kotlin andInquiryEntry.start(launchCode)in TypeScript. WatchInquiryUiModel.lifecycleand close the inquiry store when the lifecycle becomesClosedor your view goes away. The inquiry UI never closes the store you give it, on any platform. When the inquiry ends with a redirect, the UI opens it as a universal link, in the same tab on the web, and then closes the inquiry. See Inquiry UI. - Read the result. The verified identity is in
InquiryUiModel.identity, and the record your mapper built is in the vault. Read it fromVaultStoreand decode the payload yourself. See Vault. A document the inquiry issues reaches the vault on its own and shows inFolioDocumentListStore; see Folio documents.
Minimal app
Each sample creates the runtime and shows the inquiry for one launch code. launchCode stands for
the launch code your backend passed to your app.
import Combine
import SwiftUI
import UIKit
import FolioSDK
import FolioInquiryUI
final class VerifyViewController: UIViewController {
private var sdk: FolioSdk?
private var inquiry: InquiryStore?
private var lifecycle: AnyCancellable?
func verify(launchCode: String) async throws {
let config = FolioSdkConfig(
baseUrl: "https://app.folio.mobi",
organization: "<organization>",
development: nil,
logging: try FolioSdk.loggingConfig(consoleLevel: nil)
)
let sdk = try await FolioSdk.create(config: config, mapper: SavedIdentityMapper())
self.sdk = sdk
let store = try InquiryStore.mount(runtime: sdk)
inquiry = store
try store.dispatch(action: .open(entry: .start(launchCode: launchCode)))
lifecycle = store.$state
.map(\.lifecycle)
.sink { [weak self] lifecycle in
if case .closed = lifecycle { self?.finish() }
}
let platform = InquiryPlatform(nfc: sdk)
let flow = UIHostingController(rootView: FolioInquiry(store: store, platform: platform))
flow.modalPresentationStyle = .fullScreen
present(flow, animated: true)
}
private func finish() {
lifecycle = nil
dismiss(animated: true)
inquiry?.close()
inquiry = nil
}
}The SDK reads your app's identifier, version and build from the main bundle. See
iOS setup for the inquiry view FolioInquiry in SwiftUI.
Next steps
| Topic | Pages |
|---|---|
| Platform setup | iOS, Android, Web |
| The inquiry | Inquiry UI, Inquiry store, Inquiry embed |
| Verification steps | NFC chip reading, Selfie capture |
| The result | Identity records, Vault, Folio documents |
| Reference | Errors, Localization, Logging, Storage, Versions and build info |