Developer's Guide for iOS 

The IDEMIA Verify SDK - iOS v1.4.0 is intended for developers who want to verify mobile driver's licenses (mDL) within their mobile apps. This guide outlines the necessary steps to configure and use a minimum viable project to verify a mDL.

Prerequisites 

Skills required 

The integration tasks requires developers with knowledge of:

  • iOS frameworks built in Xcode 11.0 or higher
  • Swift 5.0 or higher
  • macOS 10.14 or higher

External libraries required 

  • SwCrypt - pod 'SwCrypt'
  • SwiftCBOR - pod 'SwiftCBOR'
  • DLParser - pod 'DLParser', '~> 3.0'

For optical inspection 

  • Add BiometricSDK.framework
  • Add BiometricSDKAlgorithmPlugin_F5_4_LOW75.framework
  • pod 'IDZSwiftCommonCrypto', '~> 0.13.0',
    => true
  • pod 'SwiftBytes', '~> 0.6.0'
  • pod "OpenSSL-Universal",
    => 'https://github.com/krzyzanowskim/OpenSSL.git',
    => 'master'

For line code 

Download the Verify framework from the mi-artifactory: https://mi-artifactory.otlabs.fr/artifactory/verify-sdk-ios-release/com/idemia/idverify/ios/.

  • Add LineCodeVerify.framework

For the Line Code SDK integration, please refer to the Line Code SDK Documentation.

Resources required 

The tools required for integration on a Macintosh are:

  • Xcode 11.0 or above
  • iOS SDK tools: release 11 or above (preferably latest version)
  • Physical iOS device (simulator is not supported)

SDK implementation 

The required permissions in the app info.plist file are:

  • Privacy - Bluetooth Always Usage Description
  • Privacy - Bluetooth Peripheral Usage Description
  • Privacy - Camera Usage Description

Design considerations 

User permissions 

Your iOS app must handle user permissions to protect the resources on the target mobile device. Specifically, check that the app permissions are granted by the user. If the required permissions are not granted, the SDK will throw an exception or error and may even crash.

The following permission are required:

  • Camera permission: for the QR code scan

  • Bluetooth permission: for BLE data transfer

How to create your own app 

To create your own app, follow the steps below.

  1. Add the Verify.framework file to your project by pasting the following file in folder at path: /verify-ios-tester-app/src/xcode/VerifyTesterApp/VerifyTesterApp/Frameworks/Verify.framework.

  2. Download the Verify framework and tester app from the mi-artifactory: https://mi-artifactory.otlabs.fr/artifactory/verify-sdk-ios-release/com/idemia/idverify/ios/

  3. Link Verify.framework to your project by dragging and dropping on Project Settings (General > Frameworks, Libraries, and Embedded Content).

Add pods

  • pod 'DLParser', '~> 3.0'
  • pod 'SwCrypt'
  • pod 'SwiftCBOR'
  • pod 'PPpdf417', '~> 7.2.0'

For optical inspection

  • Add BiometricSDK.framework
  • Add BiometricSDKAlgorithmPlugin_F5_4_LOW75.framework
  • pod 'IDZSwiftCommonCrypto', '~> 0.13.0',
    => true
  • pod 'SwiftBytes', '~> 0.6.0'
  • pod 'OpenSSL-Universal'

For line code

  • Add LineCodeVerify.framework

For the IDEMIA Line Code SDK - iOS integration, please refer to the Line Code SDK Documentation.

  1. Call IDVerifyTerminal.getClient and initialize the IDVerifyTerminal shared object in the AppDelegate.swift file.

    Swift
    1//Only for Optical Inspection
    2let license = BioSDKLicense(lkmsURL:serverEndpointUrl, lkmsProfileId: profileID, lkmsApiKey: apiKey)

    Note:

    • Minimum threshold for the BioTemplate authentication score (Optical Inspection use case) is 3500 by default.
    • Internet connection is required for 1st time transaction of Optical Inspection for attributes retrieval. The Mobile ID credential is downloaded from server only once and will not be downloaded again until either expired or app is reinstalled/data cleared.
    • By default no logs shall be visible on logcat from the SDK. Use enableDebug(true) for debugging purpose only if needed and toggle it to false for production release.
    Swift
    1let config = Configs.Builder()
    2 .enableDebug(isDebuggable: isDebuggable)
    3 .setBioSDKLicense(bioSDKLicense: license) //Optional: required only if you're to use Optical Inspection
    4 .build()
    5
    6sharedVSDKClient = IDVerifyTerminal.getClient(configs: config)

Obtain a LKMS license

Please contact our support team to get an LKMS license for your app. You can skip this step if your app doesn't intend to use "Optical Inspection" feature of the IDEMIA Mobile ID Verify App.

  1. Scan the QR or PDF417 codes.

    Swift
    1/**
    2 * Response callback for parse engagement QR code data or PDF417 raw data from physical or **Mobile ID** credential holder
    3 */
    4 //MARK: parsed QRCode
    5 func parsedDataForQRCode(trimmedQRCode: String){
    6 DispatchQueue.global(qos: .default).asyncAfter(deadline: .now() + 0.2) {
    7 let config = self.formAndReturnAppConfigsParamForAPI(qrString: trimmedQRCode)
    8 sharedVSDKClient?.initDeviceEngagement(apiConfig: config, responseCallback: self)
    9
    10 }
    11 }
    12
    13 //MARK: parsed 2DBarCode
    14 func parsedDataFor2DBarCode(trimmedQRCode: String){
    15 DispatchQueue.global(qos: .default).asyncAfter(deadline: .now() + 0.2) {
    16 let config = self.formAndReturnAppConfigsParamForAPI(qrString: trimmedQRCode)
    17 sharedVSDKClient?.parsePDF417(apiConfig: config, responseCallback: self)
    18 }
    19 }
    20
    21 // Returns ApiConfigs with all the parameters
    22 func formAndReturnAppConfigsParamForAPI(qrString qr: String?) -> ApiConfigs? {
    23 guard let tempQRString = qr else {
    24 return nil
    25 }
    26 // Build app configs
    27 let apiConfigs = ApiConfigs.ConfigBuilder()
    28 .withData(inputData:tempQRString)
    29 .setAgeOverNN(age: pickedAge)
    30 .build()
    31 return apiConfigs
    32 }
  2. Handle the response result after scanning the QR code or 2D barcode. After scanning the QR code successfully, you will get the result in onSuccess.

    Swift
    1func onSuccess(response: Any?){
    2 }
    3 func onError(error: VerifyError){
    4
    5 }
  3. Send a request to the Mobile ID App to get the license details.

    The sendRequest() method will return the response from the user's Mobile ID credential. If it's received it successfully, then all the attributes of the Mobile ID App response appear in the view controller.

    Swift
    1// Set 'appConfig' as follows if you want to use all attributes as optional parameters
    2var dataItems = getMandatoryParams()
    3dataItems.append(contentsOf: getOptionalParams())
    4
    5let apiConfigs = AppConfigs.MIDRequestBuilder()
    6            .addParam(listParams: dataItems)
    7            .build()
    Swift
    1// Set 'appConfig' as follows if you want to use only the suggested attributes as optional parameters
    2var dataItems = getOptionalParams() let apiConfigs =
    3AppConfigs.MIDRequestBuilder() .addParam(listParams: paramsList, useDefaults:
    4true) .build()
    Swift
    1//Send the request by using `appConfig` which you set earlier
    2sharedVSDKClient?.sendRequest(apiConfig: apiConfigs, responseCallback: self)
    3}
    Swift
    1// send request using new namespace and paramList support
    2
    3func sendrequest(){
    4
    5 var aamvaParamsList = [MIDRequestParam]()
    6 var namespaceParamList = [String: [MIDRequestParam]]()
    7 var isoParamsList = [MIDRequestParam]()
    8 isoParamsList.append(MIDRequestParam(paramName: MIDParamConstants.GIVEN_NAME))
    9 isoParamsList.append(MIDRequestParam(paramName: MIDParamConstants.FAMILY_NAME))
    10 isoParamsList.append(MIDRequestParam(paramName: MIDParamConstants.RESIDENT_ADDRESS))
    11 isoParamsList.append(MIDRequestParam(paramName: MIDParamConstants.RESIDENT_CITY))
    12 isoParamsList.append(MIDRequestParam(paramName: MIDParamConstants.RESIDENT_CITY))
    13
    14 namespaceParamList[MIDParamConstants.DOCTYPE_ORG_AAMVA_US] = aamvaParamsList
    15 namespaceParamList[MIDParamConstants.NAMESPACE_18013_5 ] = isoParamsList
    16
    17 let apiConfigs = ApiConfigs.MIDRequestBuilder()
    18 .version(version: MIDParamConstants.REQUEST_VERSION)
    19 .addDocType(docType: "my.cusom.docType.custom1") //example docType1
    20
    21 //1. add
    22 .addParams(namespaceParamList)
    23 // add again to test if duplicates are removed
    24 .addParams(MIDParamConstants.NAMESPACE_18013_5,isoParamsList)
    25 //2. add more params one by one with custom namespce
    26 .addParam(MIDParamConstants.NAMESPACE_18013_5,MIDRequestParam(paramName: "custom_param1"))
    27 .addParam("my.custom.namespace",MIDRequestParam(paramName: "custom_param1"))
    28
    29 .addParam("my.custom.namespace",MIDRequestParam(paramName: "custom_param2"))
    30 .addParam("my.custom.namespace",MIDRequestParam(paramName: "custom_param3"))
    31 //duplicates will be removed
    32 .addParam("my.custom.namespace",MIDRequestParam(paramName: "custom_param1"))
    33 .addParam("my.custom.namespace",MIDRequestParam(paramName: "custom_param3"))
    34 //3. or add a custom namespace like this
    35 .addParams("my.custom.namespace2", [
    36 MIDRequestParam(paramName: "custom_param_nm21"),
    37 MIDRequestParam(paramName: "custom_param_nm22"),
    38 MIDRequestParam(paramName: "custom_param_nm23"),
    39 MIDRequestParam(paramName: "custom_param_nm21") ]//duplicate
    40 )
    41
    42 .buildDoc() //build doctype1
    43 .addDocType(docType: "my.cusom.docType.custom2") //example docType2
    44 .addParams("my.custom.namespace2", [
    45 MIDRequestParam(paramName: "custom_param_nm21"),
    46 MIDRequestParam(paramName: "custom_param_nm22"),
    47 MIDRequestParam(paramName: "custom_param_nm23"),
    48 MIDRequestParam(paramName: "custom_param_nm21") ]//duplicate
    49 )
    50 .buildDoc() //build doctype2
    51
    52 .build()
    53
    54 //call sendRequest API
    55 sharedVSDKClient?.sendRequest(apiConfig: apiConfigs, responseCallback: self)
    56 // 3. Read request params supplied from app and make the request structure accordingly.
    57
    58}
  4. Callback for the sendRequest IDEMIA Verify SDK - iOS API to receive and display the response data from the Mobile ID App.

    Swift
    1/**
    2 * Request callback for the `sendRequest` SDK API to receive and display the response data from the mDL.
    3 */
    4
    5 func onSuccess(response: Any?){
    6 }
    7 func onError(error: VerifyError){
    8 }
    9 func onRequestCanceled(response: Any?){
    10 }
    11 func onProgress(totalBytesRecived: Int){
    12 }
    13 func onRequestSent(status: Bool?){
    14 }
    15 func currentBLEStatus(currentState: TransferState){
    16 }
  5. You can cancel the transaction at any time by calling the cancelRequest() method.

    Swift
    1sharedVSDKClient?.cancelRequest(responseCallback: self,cancellationReason: .CANCELED_BY_USER)
  6. Get the SDK version by calling it directly with class name.

    Swift
    1IDVerifyTerminal.version

Updates and additions 

  • Added optional method withImage added in ApiConfigs.ConfigBuilder for initDeviceEngagement which takes the captured device screenshot image (while scanning the compact QR code) for BioTemplate authentication
  • Added optional method setBioSDKLicense is added in Configs.Builder to supply the LKMS license detail to the IDEMIA Verify SDK - iOS.
  • Added model class OIDLDataModel, which encapsulates the attributes list and corresponding security checks for the Optical Inspection QR code result
  • Added the new model class OpticalInspectionAuth to return security checks related to Optical Inspection.

Request parameters 

Item#
Identifier
Param Name
CBOR Type
1ADMINISTRATIVE_NUMBERadministrative_numberMajor type 3
2GENDERgenderMajor type 3
3HEIGHTheightMajor type 0
4WEIGHTweightMajor type 0
5EYE_COLOReye_colorMajor type 3
6HAIR_COLORhair_colorMajor type
7BIRTH_PLACEbirthplaceMajor type 3
8RESIDENT_ADDRESSresident_addressMajor type 3
9PORTRAIT_CAPTURE_DATEportrait_capture_dateTag value 0 of major type 6
10AGE_IN_YEARSage_in_yearsMajor type 0
11AGE_BIRTH_YEARage_birth_yearMajor type 0
12AGE_OVER_NNage_over_NNValue 20/21 of major type 7
13ISSUING_JURISDICTIONissuing_jurisdictionMajor Type 3
14NATIONALITYnationalityMajor type 3
15RESIDENT_CITYresident_cityMajor type 3
16RESIDENT_STATEresident_stateMajor type 3
17RESIDENT_POSTAL_CODEresident_postal_codeMajor type 3
18BIOMETRIC_TEMPLATE_XXbiometric_template_xxMajor type 2
19NAME_NAT_CHARname_nat_charMajor type 3
20MGMT_NEXT_UPDATEmgmt_nextupdateTag value 0 of major type 6
21FAMILY_NAMEfamily_nameMajor type 3
22GIVEN_NAMEgiven_nameTag value 0 of major type 6
23BIRTHDATEbirthdateTag value 0 of major type 6
24ISSUE_DATEissue_dateTag value 0 of major type 6
25EXPIRY_DATEexpiry_dateMajor type 3
26ISSUING_COUNTRYissuing_countryMajor type 3
27ISSUING_AUTHORITYissuing_authorityMajor type 3
28DOCUMENT_NUMBERdocument_numberMajor type 3
29PORTRAITportraitMajor type 2
30MGMT_LAST_UPDATEmgmt_lastupdateTag value 0 of major type 6
31MGMT_VALIDITYmgmt_validityTag value 0 of major type 6
32ONLINE_TOKEN_XXXXonline_token_xxxxMajor type 3
34DRIVING_PRIVILEGESdriving_privilegesMajor type 4
35REAL_IDRealIDMajor type 3 //org.aamva namespace
36SIGNATURE_USUAL_MARKsignature_usual_markMajor type 3
37ONLINE_URL_XXXXonline_url_xxxxMajor type 3
38BIRTHDATEbirth_dateMajor type 3
39BIRTH_PLACEbirth_placeMajor type 3
40NAME_NAT_CHARname_national_characterMajor type 3

Expected results 

Data Fields
Data type/Unit
Sample Value
Action Required
administrative_numberText/String"1234453"
genderText/String"M"
heightInteger/Centimeter"157"
weightInteger/Kg"56"
eye_colorText/String"BLU"
hair_colorText/String"BLACK"
birthplaceText/String"NY"
resident_addressText/String"123, ABC Street"
portrait_capture_dateDateTime/RFC3339"1985-04-12T23:20:50Z"
age_in_yearsInteger/String"34"
age_birth_yearInteger/String"1978"
age_over_NNBoolean/String"true"
issuing_jurisdictionText/String"NY"
nationalityText/String"US"
resident_cityText/String"NY"
resident_stateText/String"NY"
resident_postal_codeText/String"58773"
name_nat_charText/String"US"
mgmt_nextupdateDateTime/RFC3339"1985-04-12T23:20:50Z"
family_nameText/String"Sample"
given_nameText/String"Joe"
birthdateDateTime/RFC3339"1985-04-12T23:20:50Z"
issue_dateDateTime/RFC3339"1985-04-12T23:20:50Z"
expiry_dateDateTime/RFC3339"1985-04-12T23:20:50Z"
issuing_countryText/String"US"
issuing_authorityText/String"NY"
document_numberInt/String"782593823"
portraitByteArray/Bytes
mgmt_lastupdateDateTime/RFC3339"1985-04-12T23:20:50Z"
mgmt_validityDateTime/RFC3339"1985-04-12T23:20:50Z"
driving_privilegesText/String"C"
RealIDBoolean/Stringtrue
signature_usual_markByteArray/Bytes
birth_dateDateTime/RFC3339"1985-04-12T23:20:50Z"
birth_placeText/String"NY"
name_national_characterText/String"US"

Expected results (PDF417 scan) 

Data Fields
Data type/Unit
Sample Value
genderText/String"M"
heightInteger/inches"71"
eye_colorText/String"BLU"
resident_addressText/String"123, ABC Street"
age_in_yearsInteger/String"34"
age_over_NNBoolean/String"true"
resident_cityText/String"NY"
resident_stateText/String"NY"
resident_postal_codeText/String"58773"
family_nameText/String"Sample"
birthdateDateTime/RFC3339"1985-04-12T23:20:50Z"
issue_dateDateTime/RFC3339"1985-04-12T23:20:50Z"
expiry_dateDateTime/RFC3339"1985-04-12T23:20:50Z"
issuing_countryText/String"USA"
document_numberInt/String"782593823"
driving_privilegesText/String"C"

Expected results (Optical Inspection) 

Data Fields
Data type/Unit
Sample Value
genderText/String"M"
family_nameText/String"Sample"
given_nameText/String"Joe"
birthdateDateTime/RFC3339"1985-04-12T23:20:50Z"
expiry_dateDateTime/RFC3339"1985-04-12T23:20:50Z"

Error codes 

Error Code
Error Code Message
Description
Action Required
101Invalid QR CodePlease try again.Unable to scan the QR code.
102QR Data item is missing or found any issueThis is a QR data issue.Unable to find some elements in the QR data item. The Mobile ID reader may abort the transaction.
103QR Code parsing errorUnable to parse Mobile ID QR code.Unable to parse the QR code that the Mobile ID App has provided.
104QR code scan errorUnable to Scan QR code may be because of invalid data or bad encoding.Unable to scan the QR code.
108License Validation for Optical Inspection FailedPlease try again with the correct credentials/ stable internet connection.Try Again.
109License expiredPlease contact support to renew the license
201Unable to initialize BLEError in initializing BLE feature of thisThe Mobile ID reader is not able to get BLE. The Mobile ID credential reader may abort the transaction.
202Device Doesn't Support BLEThis device doesn't support the BLE feature.The Mobile ID reader is not able to get BLE. The Mobile ID reader may abort the transaction.
203BLE Scanning ErrorScanning of the BLE devices failed.The Mobile ID reader is not able to scan the BLE devices. The Mobile ID reader may abort the transaction.
204Bluetooth is OFFThis device's Bluetooth is off.The Bluetooth of the device is not enabled. The Mobile ID credential reader may abort the transaction.
205BLE Scanning ErrorPlease provide the BLUETOOTH permissions
206BLE Scanning ErrorPlease enable Bluetooth to get scan results
207BLE Scanning ErrorYour device does not support BLE
208BLE Connection TimeoutUnable to create BLE communication channel with the Mobile ID device.BLE connection failure. The Mobile ID reader may abort the transaction.
301Connection LostError occurred while transferring the data.The Mobile ID reader is not able to maintain the connection with the device. The Mobile ID reader may abort the transaction.
302Error Creating RequestUnable to create the request for the Mobile ID credential.The Mobile ID credential reader is not able to create the request. The Mobile ID credential reader may abort the transaction.
303Transaction CancelledThe transaction has been cancelled by the user.Unable to scan the QR code.
304Connection FailedUnable to connect the device.There is a BLE connection failure. The Mobile ID credential reader may abort the transaction.
305Device DisconnectedUnfortunately device has disconnected. Maybe the device is not in the range of BLE.The Mobile ID credential reader may abort the transaction.
306Timed Out, Please try againBLE connection failure. The Mobile ID credential reader may abort the transaction.
307Request Incomplete.Please select one or more attributes to be included in the request to the Mobile ID credential.The Mobile ID credential reader may inspect the request, ensure request is complete, and resend. The Mobile ID credential reader may abort the transaction.
308Incomplete RequestPlease select one or more attributes to be included in the request from the Mobile ID credential.The Mobile ID credential reader may inspect the request, ensure request is complete, and resend. The Mobile ID credential reader may abort the transaction.
309Mobile ID credential Reader Authentication FailedThe optional Mobile ID credential reader authentication is present but the Mobile ID App fails to authenticate the Mobile ID credential reader. The Mobile ID App returns the error message and may include data as well.The Mobile ID credential reader may inspect the problem. The Mobile ID credential reader may continue the transaction.
310Request RejectedThe Mobile ID App indicates that the request is rejected.The Mobile ID credential reader may inspect the problem. The Mobile ID credential reader may continue the transaction.
311General ErrorThe Mobile ID App returns an error without any given reason.The Mobile ID credential reader may inspect the request, ensure request is complete, and resend. The Mobile ID credential reader may abort the transaction.
401Parsing ErrorA Mobile ID credential request encountered a data element that is not well-formed (e.g., invalid initial byte) and failed decoding data. The Mobile ID App does not return any data but the error message.The Mobile ID credential reader may inspect the request, ensure request is complete, and resend. The Mobile ID credential reader may abort the transaction.
402Invalid FormatThe Mobile ID App cannot process the requested data element due to a formatting error.
403Data Not FoundThe requested NameSpace or data element within a NameSpace is not found.
404Data Request DeniedThe release of requested data element was rejected by the Mobile ID credential holder.
405Data Not ReturnedThe Mobile ID App does not provide the requested data element without any given reason.

Test samples 

Line code sample 

linecode sample

Optical inspection sample 

PDF417 sample 

QR + BLE sample 

Note: The below screenshot is only for device engagement QR code testing. The full QR code + BLE scenario will only work with real device with the IDEMIA Mobile ID App.