iOS Integration Guide
The Persona iOS SDK lets you run identity verification flows in your iOS app from UIKit or SwiftUI. The SDK takes care of the hard parts of identity capture: selfies, government ID scanning and classification, NFC passport reads, document uploads, and silent network authentication. Each flow is configured from a template you manage in the Persona Dashboard.
Integration
The SDK requires a minimum deployment target of iOS 15.0 or later. If your app needs to support iOS versions below 15.0, please continue using the latest v2.x release.
Installation
Swift Package Manager
Manual Framework
CocoaPods (v2.x only)
To install the SDK with Swift Package Manager:
- Select your project’s Swift Packages tab.
- Click on the
+to add a package. - Add the repository URL
https://github.com/persona-id/inquiry-ios-2.git, and click Next. - Choose the package options version rule you want to use. We recommend the default (up to next major version), and click Next.
- Check that the package is being added to the right target and click Finish.
Permissions
In addition to importing the dependency, you also need to modify your Info.plist and add the required permissions:
- Navigate to your project’s settings in Xcode and click the
Infotab. - Add a new “Privacy - Camera Usage Description” (
NSCameraUsageDescription) entry (if not already present) to enable camera access. - Add a new “Privacy - Location When In Use Usage Description” (
NSLocationWhenInUseUsageDescription) entry (if not already present) to enable GPS access. Unfortunately, Apple does not provide tools to differentiate when the API is in use. Therefore, even if your app or inquiry flow does not utilize the GPS functionality, the usage string must be included because the Persona SDK supports the functionality. - Add a new “Privacy - Bluetooth Always Usage Description” (
NSBluetoothAlwaysUsageDescription) entry (if not already present) to enable bluetooth scanning. Unfortunately, Apple does not provide tools to differentiate when the API is in use. Therefore, even if your app or inquiry flow does not utilize the bluetooth functionality, the usage string must be included because the Persona SDK supports the functionality. - [Optional] If using our support for video verifications, add a new “Privacy - Microphone Usage Description” (
NSMicrophoneUsageDescription) entry (if not already present) to enable microphone access. - [Optional] If using our support for NFC verifications, “Privacy - NFC Scan Usage Description” (
NFCReaderUsageDescription) entry (if not already present) to enable NFC access.
Privacy Configuration
This SDK collects a user’s IDFV for fraud prevention purposes. In App Store Connect > Your App > App Privacy, if you haven’t already add in a “Device Identifier,” and fill out the questionnaire with the following answers:
- Usage: App Functionality (covers fraud prevention)
- Are the device IDs collected from this app linked to the user’s identity? Yes
- Do you or your third-party partners use device IDs for tracking purposes? No
Be sure to also update your privacy manifest according to the features you are making use of from the SDK. See our iOS Privacy Manifest instructions for more information.
Usage
Build and Launch an Inquiry
Persona recommends creating inquiries via API when possible
Please refer to Creating inquiries for more information. After getting up and running consider moving inquiry creation to your backend for security reasons.
Start an inquiry with a template ID, inquiry ID, or one-time link code. The samples below use a template ID — replace itmpl_EXAMPLE with your own. You can find your Inquiry Template ID in the Persona Dashboard.
When the flow is presented, the SDK takes control of the user interface. Once the flow completes, control returns to your app and the appropriate result handler is called.
UIKit
SwiftUI
Build the inquiry with Inquiry.from(templateId:delegate:) and call start(from:) with the presenting view controller.
Handle Results
Do not rely on callbacks for critical business logic
SDK callbacks are intended for coordination between your app’s UI and Persona’s UI (e.g. opening and closing the flow UI). They do NOT guarantee that data are up-to-date, and cannot be reliably used to guarantee data integrity. Webhooks should be used for logic that depends on Inquiry state.
For more information, see Accessing Inquiry status and data.
UIKit
SwiftUI
To receive the inquiry result, implement the InquiryDelegate protocol. For example:
Handle Errors
In rare cases, the Persona Inquiry SDK can encounter client-side errors that cannot be resolved. When that happens, the SDK ends the flow and reports a typed PersonaError value to your app. The most common reasons include unrecoverable networking errors, misconfigured templates (should only be encountered during development), or failing to establish a connection to the device camera. PersonaError conforms to LocalizedError, so its errorDescription returns a human-readable string suitable for display or logging.
UIKit
SwiftUI
Handle errors in your InquiryDelegate.inquiryError(_:) implementation.
Configuration
The builder API exposes a number of optional methods that let you tailor an inquiry to your integration — link it to a known user, pre-fill data, control which environment it runs in, and more. Chain any of the following on top of Inquiry.from(...) (or pass them through personaInquiry’s builder: closure in SwiftUI).
Linking to a Persona Account
accountId and referenceId are mutually exclusive. Setting an account ID clears any value previously set via referenceId.
If your integration uses Persona accounts to associate the same user across multiple inquiries, pass the account ID (prefixed with act_) to the inquiry.
UIKit
SwiftUI
Linking by Reference ID
accountId and referenceId are mutually exclusive. Setting a reference ID clears any value previously set via accountId.
To make it easier to find Inquiries in the Persona Dashboard, we recommend passing in your system’s user ID for the Inquiry reference ID.
UIKit
SwiftUI
Pre-writing Fields
If you want to add extra information to the Inquiry before the user even starts, you can pass them in as fields.
UIKit
SwiftUI
Resuming an Inquiry
When you create an Inquiry on the server, you can pass the Inquiry ID instead of the Template ID.
UIKit
SwiftUI
If the Inquiry has already started, you will need to also pass in the session token.
UIKit
SwiftUI
Overriding Device Locale
Our SDK will automatically use the language and region selected on a users device to determine localization. If your app has specific localization requirements independent of user’s device settings, you can pass the localization directly to the inquiry as follows:
UIKit
SwiftUI
Selecting an Environment
By default, an inquiry runs in the .production environment. To start an inquiry in your sandbox while you develop, pass .sandbox instead. If you maintain multiple sandbox environments, you can also identify a specific one by ID.
UIKit
SwiftUI
Redirect URI
If your template uses a step that hands off to a browser or another app (for example, an external verification provider), the SDK uses the redirect URI to return the user to your app. Provide a URL whose scheme is registered for your app.
UIKit
SwiftUI
Sharing Data with a Share Token
If a user has already verified themselves with another organization on Persona and consents to reuse that data with you, you can redeem a share token (prefixed with cnst_) when starting an inquiry. The server pulls the previously verified fields, and the inquiry only asks the user for whatever is still missing.
UIKit
SwiftUI
Customization
You can configure the styles that are applied to the inquiry template in the Persona Dashboard. For more information on using the theme editor, see our help article.
Theme Set
If you have multiple themes configured on the inquiry template, you can pick which one the SDK should use by passing its theme set ID (prefixed with thm_). If you don’t set a theme set ID, the template’s default theme is used.
UIKit
SwiftUI
Style Variant
By default, the SDK uses the light or dark variant of the active theme to match the device’s system appearance. Pass a StyleVariant to force a specific variant.
UIKit
SwiftUI
Custom Fonts
By default, the iOS SDK only has access to the device’s system font. Non system fonts can either be downloaded at runtime when uploaded to your inquiry template, or bundled into your hosting application.
Custom fonts that are not available in Persona themes are only available to customers on Enterprise plans.
Bundling a font
For example, if you choose the font ‘Rubik’ in your template’s Theme configuration, you will need to add a font file named Rubik.ttf (or any compatible format) to your project by following the instructions here.
If you need to use different font weights for a given family, name each font file such that the weight is appended to the end of the family name with a -. For example, a bold version of the Rubik font would be named Rubik-Bold.ttf. Valid font weight suffixes are Light, Regular, Medium, Bold, and ExtraBold.
Initial Loading Screen
The initial loading screen is shown after the inquiry is launched and before the first server response arrives. It is the only view in the SDK that is not configured by the server; every other screen is rendered from the theme set in the Persona Dashboard. You can replace the default loading animation with your own SwiftUI view to brand this moment.
Once the first server response arrives, subsequent loading screens use the theme configured in the Persona Dashboard and are not affected by this setting.
UIKit
SwiftUI
Government Id NFC Integration
In order to use a template that includes Government Id NFC reading capabilities on iOS, follow these steps:
- Include the PersonaNfc project in your app via SPM. You can include this in the same way you would the main Persona SDK. Make sure that the version of PersonaNfc matches the version of the main Persona SDK that you are using.
- Link the PersonaOpenSSL library into your app using SPM.
- Add the NFC capability to your app (target → signing & capabilities → + Capability → Near Field Communication Tag Reading). You will also need to add the NFC capability to the Identifier for the app in the Apple Developer portal.
- Make sure that the entitlements file for your app includes both
TAGandPACEfor the Near Field Communication Tag Reader Session Formats:text - Add a
Privacy - NFC Scan Usage Descriptionto your info.plist file, along with a description. - Add a
ISO7816 application identifiers for NFC Tag Reader Sessionto your info.plist file with these values in the following order:A0000002471001,A0000002472001, and00000000000000. - Pass in
PersonaNfcAdapter()into the Inquiry builder for the.nfcAdapterfunction. You will need to importPersonaNfcto access this.
Video Integration
In order to enable video recording over WebRTC on iOS follow these steps:
- Include the PersonaWebRtc project in your app via SPM. You can include this in the same way you would the main Persona SDK. Make sure that the version of PersonaWebRtc matches the version of the main Persona SDK that you are using.
- Link the WebRTC version 111.0.0 library into your app.
- Pass in
PersonaWebRtcAdapter()into the Inquiry builder for the.webRtcAdapterfunction. You will need to importPersonaWebRtcto access this. - Add a
Privacy - Microphone Usage Descriptionto your Info.plist file.
In order to enable local video recording upload on iOS follow these steps:
- Add a
Privacy - Microphone Usage Descriptionto your Info.plist file.
Phone Number Silent Network Authentication (SNA) Integration
In order to use a template that includes phone number silent network authentication on iOS, follow these steps:
- Include the PersonaSna project in your app via SPM. You can include this in the same way you would the main Persona SDK. Make sure that the version of PersonaSna matches the version of the main Persona SDK that you are using.
- Pass in
PersonaSnaAdapter()into the Inquiry builder for the.snaAdapterfunction. You will need to importPersonaSnato access this.
Licenses
The Persona iOS SDK is shipped with the licenses for the 3rd party software that it uses. Be sure to include these licenses in your app as well. See here for a list of the 3rd party software that we use and their associated licenses.

