This page covers everything you need to add the Incode iOS SDK to your project. It covers build requirements, variant versioning, distribution channels, On-Demand Resources, required permissions, NFC entitlements, the privacy manifest, initializing the SDK, and enabling test mode.
Build Requirements
Ensure your build environment meets the following minimum requirements:
- iOS deployment target: 13.0.
- Swift language mode: 5.0 (
SWIFT_VERSION = 5.0). - Xcode: 15.0 or higher.
- Swift Package Manager: If used, SSH/Git credentials configured for authentication to the distribution repo.
- CocoaPods: 1.15+, if you're installing via CocoaPods. You must also have SSH access to the private specs repository.
Also, ensure your devices meet the device requirements. Then complete the following steps in order.
Format a Variant Version
The Incode iOS SDK ships in build variants. A variant is a linking type plus a set of optional features. Not every module is compiled into every variant, and calling an API for a feature that is not included triggers a runtime variant assertion. Pin the exact variant version; there is no Bill of Materials. Choose the smallest variant that includes the features your flow needs to keep binary size down.
MAJOR.MINOR.PATCH-LinkingType[-Feature…]
LinkingTypeisd(dynamic, default) ors(static).- Features are appended as suffixes:
vc,l,m,nfc,ra,sna,tri.
Examples: 5.31.0-d (dynamic), 5.31.1-d-l (dynamic + login), 5.31.0-s (static).
Choose a Distribution Channel
The Incode iOS SDK is distributed as IncdOnboarding.xcframework through three channels: Swift Package Manager, CocoaPods, or a manual binary. Pick the channel that matches your project's dependency management setup. Use the exact variant version string for whichever method you choose.
Install via Swift Package Manager
Add the distribution package and pin the exact variant version:
https://github.com/Incode-Technologies-Example-Repos/IncdOnboarding-distribution.git
- In Xcode, go to File > Add Package Dependencies.
- Paste the URL above.
- Select the version matching your variant: for example,
5.31.1-d.
Install via CocoaPods
The pods are published to a private specs repo. Reference both the specs source and the pod with the variant version.
Add the specs source and the pod to your
Podfile:source 'git@github.com:Incode-Technologies-Example-Repos/IncdDistributionPodspecs.git' source 'https://cdn.cocoapods.org/' target 'YourApp' do use_frameworks! pod 'IncdOnboarding', '5.31.0-d' endRun:
pod install
Embed the Binary Manually
- Download
IncdOnboarding.xcframeworkfor your variant. - Drag it into your target and set it to Embed & Sign.
- For video variants (
-vc), also add the requiredOpenTokdependency at the version pinned for your SDK release. Verify the exact OpenTok version for the release you integrate.
Manage On-Demand Resources (ODR)
The static variant can download its ML resources at runtime instead of bundling them, reducing app size. ODR requires the static variant; the dynamic variant bundles resources in the framework.
Check whether resources are already available:
let manager = IncdOnboardingManager.shared manager.checkOnDemandResourcesAvailablity { available in guard !available else { return } // proceed to download below }Download the resources if they're not available:
manager.downloadOnDemandResources( showUI: true, vc: self, // required when showUI is true, otherwise the download UI is not shown onProgress: { progress in /* 0.0…1.0 */ }, onCompleted: { /* ready */ }, onError: { error in /* handle */ } )downloadOnDemandResourcesparameters:Parameter Type Default Notes showUIBool?nilShow the built-in downloading UI. When true,vcmust also be set.vcUIViewController?nilParent view controller for the downloading UI. Only used if showUIistrue.onProgress((Double) -> Void)?nilCalled as progress changes, from 0.0to1.0.onCompleted(() -> Void)?nilCalled when the download completes or resources are already present. onError((Error) -> Void)?nilCalled when an error occurs. Free disk space when you're done with the resources:
manager.removeOnDemandResources()
Add Required Permissions
Add the following usage-description keys to your Info.plist for the modules your flow uses. iOS rejects the app at runtime and in App Review if a capability is used without its key.
| Key | Required For |
|---|---|
NSCameraUsageDescription |
ID Capture, Selfie, Face Authentication, QR Scan, Video Conference, and Video Selfie |
NSMicrophoneUsageDescription |
Video Conference; Video Selfie when audio or voice consent is enabled |
NSLocationWhenInUseUsageDescription |
Geolocation |
NFCReaderUsageDescription |
NFC |
NSPhotoLibraryAddUsageDescription |
Saving captured images to the photo library |
Example:
<key>NSCameraUsageDescription</key>
<string>We use the camera to capture your ID and a selfie for identity verification.</string>
<key>NSMicrophoneUsageDescription</key>
<string>We use the microphone to record your voice consent.</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>We use your location to verify your address.</string>
Provide your own wording. These strings are shown in the system permission prompt.
Enable NFC Entitlements (-nfc variant only)
For NFC reading, enable the Near Field Communication Tag Reading capability and declare the ISO 7816 application identifiers the SDK reads. For example:
A0000002471001
A0000002472001
00000000000000
The NFC module reads e-passport chips using AES/3DES (DESede) secure messaging; see Security.
Ship the Privacy Manifest (PrivacyInfo.xcprivacy)
The SDK ships a privacy manifest. It declares no tracking (NSPrivacyTracking = false) and the following collected data types, all linked to the user and used for app functionality (not tracking):
- Name
- Phone number
- Physical address
- Precise location
- Photos or videos
- User ID
- Device ID
Declared required-reason API usage:
NSPrivacyAccessedAPICategoryUserDefaults: Reason1C8F.1(SDK preference storage)NSPrivacyAccessedAPICategoryFileTimestamp: ReasonsC617.1,3B52.1(resource validation/TRI)
When you submit your app, make sure your app-level privacy disclosures on App Store Connect are consistent with the data your chosen flow collects.
Initialize the SDK
Initialize the SDK once, early in the app lifecycle. The idiomatic place is application(_:didFinishLaunchingWithOptions:) in your AppDelegate, or your SwiftUI App startup. Call initIncdOnboarding on the shared manager:
import IncdOnboarding
func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil
) -> Bool {
IncdOnboardingManager.shared.initIncdOnboarding(
url: "<YOUR_API_URL>",
apiKey: "<YOUR_API_KEY>"
) { success, error in
// `success` is `true` once the SDK is ready; `error` is an `IncdInitError` on failure.
}
return true
}
url: Your Incode API base URL, provided by Incode.apiKey: Your API key, provided by Incode.e2eeURL: An optional separate endpoint for end-to-end encryption.clientExperimentId: An optional A/B experiment identifier.loggingEnabled: SDK diagnostic logging. Defaults totrue; set tofalseto disable logs.testMode: Run against simulators. Defaults tofalse; see Enable Test Mode.
The trailing completion closure reports (Bool?, IncdInitError?). You can only make SDK API calls after initialization succeeds.
In -tri builds, an additional overload accepts a triConfiguration: IncdTRIConfiguration? parameter before the completion closure. This parameter sets the Transactional Risk Intelligence (TRI) variant configuration.
public func initIncdOnboarding(
url: String? = nil,
e2eeURL: String? = nil,
apiKey: String? = nil,
clientExperimentId: String? = nil,
loggingEnabled: Bool = true,
testMode: Bool = false,
_ completion: ((Bool?, IncdInitError?) -> Void)? = nil
)
public func initIncdOnboarding(
url: String? = nil,
e2eeURL: String? = nil,
apiKey: String? = nil,
clientExperimentId: String? = nil,
loggingEnabled: Bool = true,
testMode: Bool = false,
triConfiguration: IncdTRIConfiguration? = nil,
_ completion: ((Bool?, IncdInitError?) -> Void)? = nil
)
Initialize with an External Token
You can key a session to an identifier from your own system rather than relying only on a session token. On iOS, this is expressed as two properties on IncdOnboardingSessionConfiguration:
let session = IncdOnboardingSessionConfiguration(
externalId: "<YOUR_EXTERNAL_ID>"
)
externalId: An ID used outside the Incode Platform. If a session with the sameexternalIdalready exists, it is resumed instead of creating a new one.externalCustomerId: Similar toexternalId, but always creates a new session instead of resuming.
Pass the configuration when you start a flow. See Integration Approaches.
Check Initialization
let status = IncdOnboardingManager.shared.isSDKEntierlyInitialized
if !status.flag { print(status.error?.description ?? "") }
The "Entierly" spelling is the real, shipping property name.
This verifies init, resource availability, and jailbreak state.
Enable Test Mode
Test Mode lets you run the SDK on the iOS Simulator during development. Enable it by passing testMode: true to initIncdOnboarding:
IncdOnboardingManager.shared.initIncdOnboarding(
url: "<YOUR_API_URL>",
apiKey: "<YOUR_API_KEY>",
testMode: true // enable Test Mode for Simulator runs
)
testMode defaults to false. Set it to true only to run on simulators during development.
Danger
Warning
Remove testMode: true (or set it back to false) before you build for production. Test Mode is for development only.
What's Next
Choose your integration approach.