Skip to main content

Mobile SDK - iOS

Docs for the Android SDK are here.

This is a lightweight, fully native SDK that allows a host app to receive and store

A credential is a collection of data about a person. It's issued by a company (i.e. created and sent to a user) and stored in the company's app, on that user's device.
+ More...
Example: ACME Bank issues a KYC verification credential to Richard (an ACME user). This includes Richard's contact information and account numbers, as well as a level of confidence in the accuracy of the data.
Components: A company issues credentials using the Server SDK, and an app stores credentials using the Mobile SDK.
credentials, receive
A request (or presentation request) is a request for a presentation. It's sent by a company to a user, who chooses whether to share a presentation in response.
+ More...
Example: Hooli FinTech sends Richard a request for (a presentation of) a KYC verification credential from ACME Bank.
Components: A company creates requests using the Server SDK and routes them to users using the Web SDK. A user's app responds to requests using the Mobile SDK.
requests, and share
A presentation is a set of one or more credentials. It's shared with (or presented to) a company by a user.
+ More...
Example: Richard shares a presentation of a KYC verification credential (which ACME Bank issued to him) with Hooli FinTech.
Components: A user's app shares (or presents) presentations using the Mobile SDK, and a company verifies presentations using the Server SDK.
presentations. It works with both Swift and Objective-C native apps.

Before you begin: You need to be registered as Unum ID customer, and you need to register at least one

A holder app is an Unum ID enabled mobile app. See also: holder.
+ More...
Example: ACME Bank adds Unum ID technology to its mobile app, making it a holder app.
Components: A holder app is one using the Mobile SDK.
holder app. (You can register zero to many, depending on your use case.) You'll receive a holder app API key to use with this SDK.

Overview#

Minimum Requirements#

  • iOS 12 and above
  • English language (internationalization coming soon)

Required Permissions#

  • Camera: requested when you show the QR code scanner
  • Biometrics/Passcode: requested when you call initialize()

These permissions are requested by the SDK โ€” no action is required by the host app.

Because the SDK leverages the secure hardware of the user's device for cryptographic operations, it requires OS level user authentication. This means the user must have a lock screen biometric or passcode If the user doesn't have this set up, the SDK will prompt the user and direct them to the correct place in Settings to do so.

note

Device biometrics are typically aliases for passcodes (or similar options like PINs and patterns) and fall back to those. This is all handled at the OS level.

Setup#

Info.plist#

Because the SDK requires camera and biometric/passcode permissions, you need to add desciptions like these to the Info.plist file:

Privacy - Camera Usage Description#

This app would like to use the camera for QR code scanning.

Privacy - Face ID Usage Description#

This app would like to use Face ID for authorization.

Privacy - Touch ID Usage Description#

This app would like to use Touch ID for authorization.

Installation#

When you register a

A holder app is an Unum ID enabled mobile app. See also: holder.
+ More...
Example: ACME Bank adds Unum ID technology to its mobile app, making it a holder app.
Components: A holder app is one using the Mobile SDK.
holder app, we will send you the SDK as a compiled binary library.

Access to Current View Controller#

The SDK needs access to the current view controller to show system alerts to the user (this is essential for the SDK to work). So, you should always pass the this to the SDK like so:

UnumPresenterHelper.currentViewController = viewController

Initialization#

You should initialize the SDK when the app starts up. This will ensure the SDK is set up properly.

You can optionally include a

A DID (or decentralized identifier) identifies a participant in the Unum ID ecosystem. A participant is an issuer, subject, or verifier.
+ More...
Example: ACME Bank is identified by two DIDs, one for acting as an issuer and another for acting as a verifier. Richard, an ACME subject (user), is identified by one DID. Hooli FinTech, which acts as a verifier, is identified by one DID.
Components: The Server SDK returns DIDs for issuers and verifiers, and the Mobile SDK returns DIDs for subjects.
DID (did), which identifies a user (technically called a
A subject is a user of a holder app. Each subject uses one or more holders.
+ More...
Example: Richard is a subject (user) of the ACME Bank mobile app. He uses two holders: the app installed on his phone and his tablet.
Components: A holder app is one using the Mobile SDK, and a holder is an instance of that installed on a particular device. A subject uses one or more holders.
subject) in the Unum ID ecosystem. A returning user will already have a DID, so you should include this to ensure the SDK loads any new credentials associated with that DID as part of the initialization process.

You can optionally include the UnumCallback to be notified of the result of the initialization call.

After a user has successfully log in to the host app, and initialization call should be made to the SDK. The host app should store a reference to the user DID so that it can be passed to the initialization call. If a DID is not provided a new one will be created and returned.

let userDid = { /* retreive user DID */ }
let config = UnumInitializationConfiguration(customerId: BuildConfig.CustomerId, // your customer UUID
apiKey: BuildConfig.ApiKey, // your holder app API key
did: userDid, // (optional) include this for returning users โ€” otherwise leave empty
onError: {}, // (optional) run if there's an error
authorizeRecoveryFromBackup: { } // (optional) run when restoring from backup
)
classInitializationCallback: UnumCallback {
internal init(_ parent: MainView) {
self.parent = parent
}
let parent: MainView
func onSuccess(data: String?) {
// returned data will be user's DID if new one was created
}
func onSDKError(error: String?) {
print("SDK Error: \(error ?? "")")
}
func onAPIError(code: Int, error: String?) {
print("API Error \(error ?? "")")
}
}
UnumID.initialize(configuration: config, callback: InitializationCallback(self))

The initialization process involves creating private keys for the user using the secure hardware of the device. This requires OS level authentication, so the user will be prompted to pass a biometric check or enter their passcode. If they don't have this set up, the SDK will direct them to the correct place in Settings to do so.

Deep Links#

In the context of Unum ID, a deep link is a URL that opens a specific

A holder app is an Unum ID enabled mobile app. See also: holder.
+ More...
Example: ACME Bank adds Unum ID technology to its mobile app, making it a holder app.
Components: A holder app is one using the Mobile SDK.
holder app. For example, a link that opens the ACME Bank mobile app might look like this:

unumid://acme/presentationRequest/88d37012-f83b-453a-a1f1-d4a1bcf86aa3

The SDK uses deep links to retrieve and display a

A request (or presentation request) is a request for a presentation. It's sent by a company to a user, who chooses whether to share a presentation in response.
+ More...
Example: Hooli FinTech sends Richard a request for (a presentation of) a KYC verification credential from ACME Bank.
Components: A company creates requests using the Server SDK and routes them to users using the Web SDK. A user's app responds to requests using the Mobile SDK.
request to a user, who decides whether to share data in response. Users will typically encounter deep links displayed in the Web SDK (in QR code or button form) or sent over a communication channel (like push notification, SMS, or email).

You need to pass Unum ID deep links to the SDK to be processed. To do so, set up your host app to receive the appropriate schemas. (You can optionally add logic to determine if the deep link should be passed to the SDK.) Do this in the Target -> Info tab.

Url type

Here's an example of sending the deep link to the SDK in SceneDelegate:

func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) {
for context in URLContexts {
UnumID.acceptDeepLink(link: context.url.absoluteString)
}
}

When it receives a deep link, the SDK will display a system alert, asking the user how they want to respond to the

A request (or presentation request) is a request for a presentation. It's sent by a company to a user, who chooses whether to share a presentation in response.
+ More...
Example: Hooli FinTech sends Richard a request for (a presentation of) a KYC verification credential from ACME Bank.
Components: A company creates requests using the Server SDK and routes them to users using the Web SDK. A user's app responds to requests using the Mobile SDK.
request (that the deep link references).

QR Code Scanner#

The Unum ID deep links described above can be displayed in QR code form. This is important for cases when a user is on a non-mobile device. For example, the ACME Bank website might request that a user share an authentication credential to log into the ACME website on desktop. ACME would do so by displaying a QR code that the user scans. This would open the ACME mobile app on the user's phone and prompt the user to share the requested data.

Any QR code scanner can read an Unum ID deep link in QR code form. iOS devices support scanning directly from the native camera, but you should also allow the user to scan codes from within your app.

If you already have a QR code scanner, you can pass QR codes directly to the SDK like so:

UnumID.acceptDeepLink(link: scannedCode)

If you don't have a QR code scanner, you can use the one included in the SDK. This will automatically pass the deep link to the SDK โ€” no further action is needed from the host app.

var scannerSheet: some View {
UnumCodeScannerView(
codeTypes: [.qr],
completion: { result in
self.isShowingScanner = false
}
)
}

You can open this on a trigger of your choice. For example, you can create a "Scan QR Code" button that opens the scanner when the user clicks it:

@State var isShowingScanner = false
Button(action: {
self.isShowingScanner = true
}) {
Text("Scan QR Code")
.font(.headline)
.foregroundColor(.white)
.padding(.all)
.frame(width: 300, height: 50)
.background(Color.blue)
.cornerRadius(15.0)
}.sheet(isPresented: $isShowingScanner) {
self.scannerSheet
}

Logging#

You can turn SDK logging on and off and set the log level:

// Turn the SDK logger on or off
UnumID.log.enabled = true
// If logger enabled, set desired message log level
UnumID.log.level = .debug

Callback#

You can pass the UnumCallback to most method calls within the SDK. This adds a listener that records the result of the method call โ€“ a successful call, an SDK error, or an API error. The Initialization section shows one example of this, and here's another:

classInitializationCallback: UnumCallback {
internal init(_ parent: MainView) {
self.parent = parent
}
let parent: MainView
func onSuccess(data: String?) {
// returned data will be user DID if new one was created
}
func onSDKError(error: String?) {
print("SDK Error: \(error ?? "")")
}
func onAPIError(code: Int, error: String?) {
print("API Error \(error ?? "")")
}
}
UnumID.initialize(configuration: config, callback: InitializationCallback(self))

Handling Multiple Users#

Each user is identified by some user ID in your system and by a

A DID (or decentralized identifier) identifies a participant in the Unum ID ecosystem. A participant is an issuer, subject, or verifier.
+ More...
Example: ACME Bank is identified by two DIDs, one for acting as an issuer and another for acting as a verifier. Richard, an ACME subject (user), is identified by one DID. Hooli FinTech, which acts as a verifier, is identified by one DID.
Components: The Server SDK returns DIDs for issuers and verifiers, and the Mobile SDK returns DIDs for subjects.
DID in the Unum ID ecosystem. You simply need to store an association between each user ID and DID. That way, when your host app has a particular user ID (for example once a user is logged into your existing account system), it can pass the corresponding DID to the SDK.

If you don't have existing user IDs, you could use the DIDs themselves as user IDs. However, we recommend using separate identifiers (internal to your company), to distinguish them from DIDs, which are global to the Unum ID ecosystem.

note

The technical details of DIDs are not relevant to deploying or using Unum ID. You can think of DIDs as identifiers in the normal sense โ€” unique, random strings of characters like UUIDs.

note

The technical details of DIDs are not relevant to deploying or using Unum ID. You can think of DIDs as identifiers in the normal sense โ€” unique, random strings of characters like UUIDs.

When you initialize the SDK, you can optionally include a DID.

  • Don't include a DID for user who's new to the SDK. The SDK will generate a new one that you should store, associated with the user ID in your system.
  • Do include a DID for a user who returns to the SDK. The SDK will use this DID to access the correct stored data for that user.
important

DIDs are the only identifiers the SDK understands, so it relies entirely on the host app to pass the correct one.

For example, suppose Users 1 and 2 are associated with DIDs 1 and 2, respectively. If User 1 is using the host app, but the app passes DID 2 to the SDK, the SDK will give User 1 access to to User 2's data.

Example Flow#

  1. New User 1 logs into host app.
    • SDK is initialized with no DID.
    • SDK returns newly generated DID 1.
    • Host app stores DID 1 and associates it with User 1.
  2. New User 2 logs into host app.
    • SDK is initialized with no DID.
    • SDK returns newly generated DID 2.
    • Host app stores DID 2 and associates it with User 2.
  3. Returning User 1 logs into host app.
    • Host app retrieves DID 1 and includes it in SDK initialization.
    • SDK recognizes this is a returning user and does not generate a new DID.