---
title: "iOS SDK guide | Veriff.com"
slug: "ios-sdk-guide"
description: "Integrate with Veriff iOS SDK using Xcode, Swift Package Manager, or Cocoapods. Ensure permissions for camera, microphone, and NFC for seamless verification."
updated: 2026-04-27T09:37:58Z
published: 2026-04-27T09:37:58Z
---

> ## Documentation Index
> Fetch the complete documentation index at: https://devdocs.veriff.com/llms.txt
> Use this file to discover all available pages before exploring further.

# iOS SDK guide

## Requirements and prerequisites

### Requirements

- Veriff iOS SDK requires at **least iOS version 15.0**
- It is recommended that you use Veriff iOS SDK with the **latest stable version of Xcode available at the time of the release**.

*→ See the*[*iOS SDK migration guide*](/v1/docs/ios-migration-guide)*for additional info*

*→ See the*[*Backwards compatible changes*](/v1/docs/backwards-compatible-changes)*and ensure your systems are able to handle these*

### Prerequisites

- You have an active account with Veriff (see the [Getting Started](/v1/docs/getting-started) section)
- You have an integration with Veriff (see the [Getting Started](/v1/docs/getting-started) section)
- You have set up webhook(s) to get replies from Veriff (see the [Webhooks](/v1/docs/webhooks-guide) section)

---

## Add iOS SDK to the project

### Option 1: Using Swift Package Manager

To integrate Veriff SDK with Swift Package Manager, open **File > Swift Packages > Add Package Dependency** and add the Veriff iOS SDK Swift Package repository URL as stated below:

```plaintext
https://github.com/Veriff/veriff-ios-spm/
```

### Option 2: Using Cocoapods

To integrate Veriff SDK with Cocoapods, please add the line below to your **Podfile** and run `pod install`:

```ruby
pod 'VeriffSDK'
```

After installation is done, use the newly created `.xcworkspace` file of your project.

*→ See the*[*Cocoapods guide*](https://guides.cocoapods.org/using/using-cocoapods)**[↗]

### Option 3: Using Carthage

To integrate Veriff SDK into your Xcode project using Carthage, specify the required library below in your `Cartfile`:

```swift
binary "https://cdn.veriff.me/ios/carthage/VeriffSDK.json"
```

Run `carthage update --use-xcframeworks` and then drag and drop Veriff.xcframework from `Carthage/Build` folder to the *Frameworks, Libraries, and Embedded Content* section on your app target's *General* settings tab.

### Option 4: Using XCFramework

To integrate Veriff SDK into your project manually, please download [VeriffSDK](https://cdn.veriff.me/ios/com/veriff/veriffsdk/latest/veriffsdk.zip) [↓] (opening the link will start the download automatically).

After the download finishes, drag and drop the unzipped `Veriff.xcframework` to the *Frameworks, Libraries, and Embedded Content* section on your app target's *General* settings tab.

---

## Add permissions

### Usage descriptions

Veriff requires **camera, microphone, photo library and optionally NFC reader permissions** for capturing photos, video and scanning passports or ID cards during identification. **Your application is responsible for describing the reason why** camera, microphone, photo library and NFC reader are used. You need to add the three descriptions listed below to the `Info.plist` file of your application with the explanation of the usage.

- `NSCameraUsageDescription`
- `NSMicrophoneUsageDescription`
- `NSPhotoLibraryUsageDescription`

> [!CAUTION]
> Not adding these permissions will cause the system to shut down the application when it requests the permissions.

---

## Enable NFC scanning

The NFC scanning logic is provided as a separate framework. If this feature is enabled in your integration, you can add the framework using one of the following methods:

### Option 1: Using Swift Package Manager

To integrate VeriffNFC SDK with Swift Package Manager, open **File > Swift Packages > Add Package Dependency** and add the VeriffNFC Swift Package repository URL as stated below:

```plaintext
https://github.com/Veriff/veriff-nfc-ios-spm/
```

VeriffNFC package depends on the [OpenSSL-Universal](https://github.com/krzyzanowskim/OpenSSL)[↗] package. Please add it by following the steps described in the package’s [SPM integration section](https://github.com/krzyzanowskim/OpenSSL?tab=readme-ov-file#swift-package-manager)[↗].

### Option 2: Using Cocoapods

To integrate VeriffNFC SDK with Cocoapods, please add the line below to your **Podfile** and run `pod install`:

```ruby
pod 'VeriffNFCSDK'
```

### Option 3: Using Carthage

To integrate VeriffNFC SDK into your Xcode project using Carthage, specify the required library below in your `Cartfile`:

```plaintext
binary "https://cdn.veriff.me/ios/carthage/VeriffNFCSDK.json"
```

Run `carthage update --use-xcframeworks` and then drag and drop VeriffNFC.xcframework from `Carthage/Build` folder to the *Frameworks, Libraries, and Embedded Content* section on your app target's *General* settings tab.

VeriffNFC framework depends on the [OpenSSL-Universal](https://github.com/krzyzanowskim/OpenSSL) framework. Please add it by following the steps described in the package’s [Carthage integration section](https://github.com/krzyzanowskim/OpenSSL?tab=readme-ov-file#carthage).

### Option 4: Using XCFramework

To integrate VeriffNFC SDK into your project manually, please download [VeriffNFCSDK](https://cdn.veriff.me/ios/com/veriff/veriffnfcsdk/latest/veriffnfcsdk.zip) (opening the link will start the download automatically).

After the download finishes, drag and drop the unzipped `VeriffNFC.xcframework` to the *Frameworks, Libraries, and Embedded Content* section on your app target's *General* settings tab.

VeriffNFC framework depends on the [OpenSSL-Universal](https://github.com/krzyzanowskim/OpenSSL) framework. Please add it by [downloading the OpenSSL.xcframework](https://github.com/krzyzanowskim/OpenSSL?tab=readme-ov-file#output-formats) and repeating the same steps you have done for `VeriffNFC.xcframework`.

<meta charset="utf-8">

### NFC scanning permissions

1. Add `NFCReaderUsageDescription` description to `Info.plist`.
2. In the Info.plist file, define the list of application IDs or AIDs it can connect to (the AID is a way of uniquely identifying an application on a ISO 7816 tag, which is usually defined by a standard)

```markup
<key>com.apple.developer.nfc.readersession.iso7816.select-identifiers</key>
<array>
	<string>D23300000045737445494420763335</string>
	<string>A0000002471001</string>
	<string>A0000002472001</string>
	<string>00000000000000</string>
</array>
```

1. Introduce a new entitlement for NFC scanning, a feature made available from iOS 13 onwards. Xcode automatically adds this entitlement when you activate the Near Field Communication Tag Reading feature in the target Signing & Capabilities. Following the activation of this feature, the *.entitlements file should include the TAG format.

```markup
<key>com.apple.developer.nfc.readersession.formats</key>
<array>
    <string>TAG</string>
</array>
```

Note: due to Apple's policies, you may be required to **record and share a proof video of using the NFC**. You can download and use the pre-recorded video linked below. If this does not solve the issue, please contact our support team.

[](https://cdn.document360.io/5c26138b-b1e9-404e-a2e4-c83a49245be7/Images/Documentation/Veriff_nfc_used_iOs (1).zip)Veriff_nfc_used_iOs (1)5.99 MB[**](https://cdn.document360.io/5c26138b-b1e9-404e-a2e4-c83a49245be7/Images/Documentation/Veriff_nfc_used_iOs (1).zip)

### NFC data listener

If enabled for your integration and the end-user reaches the NFC step, you **can receive NFC data extraction status.**See the [iOS SDK: NFC data listener](/v1/docs/ios-sdk-nfc-data-listener) article for more info.

---

## Start the verification flow

### Step 1: Import `Veriff` framework

SwiftObjective-C

```swift
import Veriff
```

```objectivec
@import Veriff;
```

### Step 2: Start the verification flow

Call the method below with the defined parameters.

SwiftSwift UIObjective-C

```swift
// SwiftUI
let veriff = VeriffSdk.shared
veriff.startAuthentication(sessionUrl: sessionUrl)

// UIKit
let veriff = VeriffSdk.shared
veriff.startAuthentication(sessionUrl: sessionUrl, presentingFrom: yourViewController)
```

```objectivec
VeriffSdk *veriff = [VeriffSdk shared];
[veriff startAuthenticationWithSessionUrl:sessionUrl presentingFrom:yourViewController];
```

```SwiftUI
let veriff = VeriffSdk.shared
veriff.startAuthentication(sessionUrl: sessionUrl)
```

| Parameters | Description |
| --- | --- |
| `sessionUrl`* | A combination of the `base URL` and the `sessionToken`, created as soon as a verification session is created. You can find its value in the response payload of your <meta charset="utf-8">[POST /sessions](https://veriff-dev-documentation.document360.io/apidocs/v1sessions)[↗] call, as `verification.url`. See [Create a verification session](/v1/docs/how-to-generate-sessions-manually) article or more info. |
| `configuration` | Optional `VeriffConfiguration` object. See the [Customize the SDK](/v1/docs/ios-sdk-guide#customize-the-sdk) explanation below for instructions on how to use it. |
| `presentingFrom` | The ViewController of your app will present the Veriff SDK UI. Presentation always happens modally. This parameter should not be used in SwiftUI projects. |

* Required parameter

> [!NOTE]
> A session is valid for 7 days and expires automatically after that.

### What happens after the end-user leaves the flow?

When the end-user leaves the verification flow, i.e. a session is canceled or finished, the Veriff SDK is closed. The end-user is taken back to your application. The **end-user flow completion status** is returned to the host application, see [Verification session status](/v1/docs/ios-sdk-guide#get-verification-session-status) explanation below for more info.

---

## Verification session status

To receive session results, you must conform to the `VeriffSdkDelegate` protocol and assign a delegate to the `VeriffSdk` instance.

SwiftObjective-C

```swift
veriff.delegate = self
```

```objectivec
veriff.delegate = self;
```

> [!NOTE]
> **This is not the verification session decision.**
> 
> This indicates whether the end-user was able to complete all the steps in the verification flow or not.

The Veriff iOS SDK returns a result code by calling `sessionDidEndWithResult`:

SwiftObjective-C

```swift
extension VerificationService: VeriffSdkDelegate {
    func sessionDidEndWithResult(_ result: Veriff.Result) {
        switch result.status {
        case .done:
            // The end-user successfully submitted the session
            break
        case .canceled:
            // The end-user canceled the verification process.
            break
        case .error(let error):
            switch error {
                // ...
            }
        }
    }
}
```

```objectivec
- (void)sessionDidEndWithResult:(VeriffResult *)result {
    switch (result.status) {
    case VeriffStatusDone:
        // The end-user successfully submitted the session, the session is completed from their perspective
        break;
    case VeriffStatusCanceled:
        // The end-user canceled the verification process
        break;
    case VeriffStatusError:
        // An error occurred during the flow
        if (result.error == nil) { break; }
        switch (result.error.code) {
            // ...
        }
    }
}
```

Inside the `VeriffStatusError` case you can do the following to check the error reason:

- In Swift: check the associated value (`Veriff.Error`) passed by error status
- In Objective-C: check `result.error.code` (`VeriffErrorCode`)

The Veriff SDK always shows an error screen itself. The errors returned by the `VeriffSdkDelegate` are meant for informing the host application.

---

## Verification session decision

Veriff returns info about the verification session decision, extracted data, registries checks etc via **webhooks**. You need to set up webhooks and tie them to your system.

→*See Webhooks Guide > [Set up webhooks](https://veriff-dev-documentation.document360.io/docs/webhooks-guide#set-up-webhooks) sub-section for detailed overview of the setup process*

---

## Customize the SDK

> [!NOTE]
> <meta charset="utf-8">SDK customization is optional

It is possible to customize the look and feel of the UI to match your branding. You can change primitives such as colors and fonts, set the language settings for the SDK, and change if/how an intro screen is displayed.

### Match the brand

If you decide to customize the SDK colors, set the `branding` property of `VeriffSdk.Configuration` before you start the verification.

Note: all custom values for branding are optional. If a value is not provided for them, the default Veriff color and logo will be used.

The `Branding` class allows customization of the navigation bar title image, button corner radius, font and following colors:

- `logo` - navigation bar logo (see [below](/v1/docs/ios-sdk-guide#custom-logo-image-dimensions) for explanation)
- `background` - screen and dialog background
- `onBackground` - non-surface content (such as text, icons) displayed on the `background` color
- `onBackgroundSecondary` - secondary non-surface content (such as text) displayed on the `background` color
- `onBackgroundTertiary` - tertiary non-surface content (such as text) displayed on the `background` color
- `primary` - primary surfaces (such as buttons) displayed on the `background` color
- `onPrimary` - non-surface content (such as text) displayed on `primary` surfaces
- `secondary` - secondary surfaces (such as bullet points and illustrations) displayed on the `background` color
- `onSecondary` - non-surface content (such as text) displayed on `secondary` surfaces
- `cameraOverlay` - overlay surface color on top of the camera preview screen
- `onCameraOverlay` - non-surface content (such as text, icons) displayed on `cameraOverlay`
- `onCameraOverlaySecondary` - secondary non-surface content (such as text) displayed on `cameraOverlay`
- `outline` - outlines and boundaries of UI elements (such as text inputs)
- `error` - error indicators (such as text, borders, icons) displayed on `background` color
- `success` - success indicators (such as borders, icons) displayed on `background` color
- `feedbackSuccessBackground` - surface color for success feedback
- `onFeedbackSuccess` - non-surface content (such as text) displayed on `feedbackSuccessBackground`
- `feedbackErrorBackground` - surface color for error feedback
- `onFeedbackError` - non-surface content (such as text) displayed on `feedbackErrorBackground`

*→ See the [Visual SDK customization guides](https://devdocs.veriff.com/docs/sdk-guide#visual-sdk-customization-guides) article for design examples*

SwiftObjective-C

```swift
let branding = VeriffSdk.Branding()
branding.logo = UIImage(named: "logo.png")
branding.background = UIColor.background
branding.onBackground = UIColor.onBackground
branding.onBackgroundSecondary = UIColor.onBackgroundSecondary
branding.onBackgroundTertiary = UIColor.onBackgroundTertiary
branding.primary = UIColor.primary
branding.onPrimary = UIColor.onPrimary
branding.secondary = UIColor.secondary
branding.onSecondary = UIColor.onSecondary
branding.cameraOverlay = UIColor.cameraOverlay
branding.onCameraOverlay = UIColor.onCameraOverlay
branding.onCameraOverlaySecondary = UIColor.onCameraOverlaySecondary
branding.outline = UIColor.outline
branding.error = UIColor.error
branding.success = UIColor.success
branding.feedbackSuccessBackground = UIColor.feedbackSuccessBackground
branding.onFeedbackSuccess = UIColor.onFeedbackSuccess
branding.feedbackErrorBackground = UIColor.feedbackErrorBackground
branding.onFeedbackError = UIColor.onFeedbackError
branding.buttonRadius = CGFloat.cornerRadius
branding.font = VeriffSdk.Branding.Font(regular: "Font", medium: "Font-Medium", bold: "Font-Bold")
```

```objectivec
VeriffBranding *branding = [[VeriffBranding alloc] init];
branding.logo = [UIImage imageNamed:@"logo.png"];
branding.background = [UIColor background];
branding.onBackground = [UIColor onBackground];
branding.onBackgroundSecondary = [UIColor onBackgroundSecondary];
branding.onBackgroundTertiary = [UIColor onBackgroundTertiary];
branding.primary = [UIColor primary];
branding.onPrimary = [UIColor onPrimary];
branding.secondary = [UIColor secondary];
branding.onSecondary = [UIColor onSecondary];
branding.cameraOverlay = [UIColor cameraOverlay];
branding.onCameraOverlay = [UIColor onCameraOverlay];
branding.onCameraOverlaySecondary = [UIColor onCameraOverlaySecondary];
branding.outline = [UIColor outline];
branding.error = [UIColor error];
branding.success = [UIColor success];
branding.feedbackSuccessBackground = [UIColor feedbackSuccessBackground];
branding.onFeedbackSuccess = [UIColor onFeedbackSuccess];
branding.feedbackErrorBackground = [UIColor feedbackErrorBackground];
branding.onFeedbackError = [UIColor onFeedbackError];
branding.buttonRadius = 5;
branding.font = [[VeriffBrandingFont alloc] initWithRegular: @"Font" medium: @"Font-Medium" bold: @"Font-Bold"];
```

### Custom logo image dimensions

For optimal results, we recommend that the height of your custom logo image be kept under 40 points, and the width under 90 points. If your logo exceeds these dimensions, it will be compressed while preserving its original aspect ratio.

### Intro screen

It is possible to customise if the end-user flow begins with Veriff intro screen or no intro screen at all.

In some cases, it is possible to skip the Veriff’s generic introduction screen and use your own before Veriff’s SDK is launched.

> [!NOTE]
> <meta charset="utf-8">Check with your **Solutions Engineer** to confirm if this feature can be enabled for your integration

If it is possible, the following will happen:

- You agree your own introduction screen visuals and copy with our Solutions Engineer and get relevant legal documents signed in case they are needed
- After that Veriff will enable custom introduction screen from backend for your integrations
- After you have implemented your own introduction screen you can change the configuration option specified below

SwiftObjective-C

```swift
configuration.customIntroScreen = true
```

```objectivec
configuration.customIntroScreen = YES;
```

> [!CAUTION]
> Adding the configuration alone in your app is not enough to enable the custom intro screen. Make sure to contact your solutions engineer so they can enable the feature for your integration.

### User interface locale settings

The Veriff iOS SDK allows setting the language of the SDK. In order to use this feature, please set the `languageLocale` property of `VeriffSdk.Configuration` before you start the verification.

SwiftObjective-C

```swift
let locale = Locale(identifier: "et")
```

```objectivec
NSLocale *locale = [NSLocale alloc] initWithLocaleIdentifier:@"et"];
```

**Create the configuration object**

SwiftObjective-C

```swift
let configuration = VeriffSdk.Configuration(branding: branding, languageLocale: locale)
```

```objectivec
VeriffConfiguration *configuration = [[VeriffConfiguration alloc] initWithBranding:branding languageLocale:locale];
```

*→ See*[*Supported languages in SDKs*](/v1/docs/sdk-guide#supported-languages)*article for more info*

### Light/dark mode

**Light/dark mode is supported through branding settings** (`Branding` object), but not through automatic system detection. You can define two sets of branding colors and manually switch between them based on the end-user's system preference. This means that **runtime theme switching is not supported**: if the end-user flow is already started with provided set of colors, changing theme in the setting will not be reflected in the SDK.

In a nutshell it works as follows:

1. You create two separate `Branding` configurations (one for light, one for dark) for your host app.
2. Your host app detects the end-user’s system's dark/light mode.
3. You pass the appropriate branding configuration when launching the Veriff SDK.

*→ See*[*branding properties list*](/v1/docs/ios-sdk-guide#match-the-brand)*above.*

#### Step 1: create two branding configurations

**Light mode**

The sample code below uses placeholder color values. Ensure that you use your brand colors.

```swift
let lightBranding = VeriffSdk.Branding()

// Background colors
lightBranding.background = UIColor.white
lightBranding.onBackground = UIColor.black
lightBranding.onBackgroundSecondary = UIColor.gray
lightBranding.onBackgroundTertiary = UIColor.lightGray

// Primary colors
lightBranding.primary = UIColor.blue
lightBranding.onPrimary = UIColor.white

// Secondary colors
lightBranding.secondary = UIColor.lightGray
lightBranding.onSecondary = UIColor.black

// Camera overlay
lightBranding.cameraOverlay = UIColor.black.withAlphaComponent(0.6)
lightBranding.onCameraOverlay = UIColor.white
lightBranding.onCameraOverlaySecondary = UIColor.white

// Feedback colors
lightBranding.feedbackSuccessBackground = UIColor.lightGreen
lightBranding.onFeedbackSuccess = UIColor.darkGreen
lightBranding.feedbackErrorBackground = UIColor.lightRed
lightBranding.onFeedbackError = UIColor.darkRed

// Utility colors
lightBranding.outline = UIColor.gray

// Optional: Custom logo
lightBranding.logo = UIImage(named: "your-logo-light")

// Optional: Button radius
lightBranding.buttonRadius = 8.0

// Optional: Custom fonts
let customFont = VeriffSdk.Branding.Font(
    regular: "YourFont-Regular",
    medium: "YourFont-Medium",
    bold: "YourFont-Bold"
)
lightBranding.font = customFont
```

**Dark mode**

The sample code below uses placeholder color values. Ensure that you use your brand colors.

```swift
let darkBranding = VeriffSdk.Branding()

// Background colors (inverted for dark mode)
darkBranding.background = UIColor.black
darkBranding.onBackground = UIColor.white
darkBranding.onBackgroundSecondary = UIColor.lightGray
darkBranding.onBackgroundTertiary = UIColor.gray

// Primary colors (adjusted for dark mode)
darkBranding.primary = UIColor.systemBlue
darkBranding.onPrimary = UIColor.white

// Secondary colors
darkBranding.secondary = UIColor.darkGray
darkBranding.onSecondary = UIColor.white

// Camera overlay
darkBranding.cameraOverlay = UIColor.white.withAlphaComponent(0.3)
darkBranding.onCameraOverlay = UIColor.black
darkBranding.onCameraOverlaySecondary = UIColor.black

// Feedback colors
darkBranding.feedbackSuccessBackground = UIColor.lightGreen
darkBranding.onFeedbackSuccess = UIColor.darkGreen
darkBranding.feedbackErrorBackground = UIColor.lightRed
darkBranding.onFeedbackError = UIColor.darkRed

// Utility colors
darkBranding.outline = UIColor.lightGray

// Optional: Dark mode logo
darkBranding.logo = UIImage(named: "your-logo-dark")

darkBranding.buttonRadius = 8.0
darkBranding.font = customFont
```

#### Step 2: detect system theme

The sample code below uses placeholder values. Your production code must reference your real values.

```swift
// Detect current system theme
let isDarkMode = UITraitCollection.current.userInterfaceStyle == .dark
```

#### Step 3: launch app with appropriate branding configuration

The sample code below uses placeholder values. Your production code must reference your real values.

```swift
// Select branding based on system theme
let branding = isDarkMode ? darkBranding : lightBranding

// Create configuration with selected branding
let configuration = VeriffSdk.Configuration(branding: branding, languageLocale: nil)

// Launch SDK
VeriffSdk.shared.startAuthentication(
    sessionUrl: sessionUrl,
    configuration: configuration,
    presentingFrom: viewController
)
```

#### **Best practices**

- Define both light and dark variants for all colors
- Test with actual system dark mode toggle
- Ensure sufficient contrast for accessibility (WCAG AA minimum)
- Store theme configurations for easy updates
- Use proper color values that work in both themes
- Do not use hardcoded colors without theme consideration

---

## Changelog

| Date | Description |
| --- | --- |
| Apr 27, 2026 | [Light/dark mode](/v1/docs/ios-sdk-guide#lightdark-mode) color tokens list updated |
| Mar 17, 2026 | - Updated **Customize the SDK** section with new branding colors - [Light/dark mode](/v1/docs/ios-sdk-guide#lightdark-mode) section added |
| Feb 3, 2026 | - Minimum version bumped to iOS 15.0 - Link to new article [iOS SDK: NFC data listener](/v1/docs/ios-sdk-nfc-data-listener) article added to [Enable NFC scanning](/v1/docs/ios-sdk-guide#enable-nfc-scanning) section |
| Dec 12, 2025 | Duplicate word removed |
| Jun 6, 2025 | Header “Article versioning” renamed to “Changelog” |
| Apr 23, 2025 | “Enable NFC scanning” section added |
| Mar 12, 2025 | Documentation published |

## Related

- [Create verification session](/how-to-generate-sessions-manually.md)
- [Intro to the API](/quick-guide-of-idv-using-the-api.md)
- [Backwards compatible changes](/backwards-compatible-changes.md)
- [iOS SDK migration guide](/ios-migration-guide.md)
- [iOS SDK changelog](/ios-changelog.md)
- [Webhooks Guide](/webhooks-guide.md)
