iOS Dynamic SDK Integration

πŸ“˜

Sample Project

You can find the sample project for a complete iOS Integration in dynamic mode.

If you require more control over the journey and order of the steps or show custom screens between ID verification steps, you can use IDWise SDK in dynamic mode. This mode allows you to start specific steps and for you application to regain control after each step. Please note this integration mode requires more code and responsibility on your side.

For an overview for end to end sequence diagram refer to Dynamic SDK Integration Overview.

Starting a new journey in dynamic mode

IDWise SDK is designed to start on top of a UIViewController in your application. Each user onboarding or verification transaction is named a user journey.

To start a new dynamic journey just provide the UIViewController from which you want the flow to start then call IDWise.initialize method first with your provided client key and then you can call IDWise.startDynamicJourney method. If initialization is failed for any reason, you will get an error object with a code and a message explaining the reason of the error. In the following example, we called initialize method and then called startJourney method.

The IDWiseSDK.initialize method accepts clientKey and theme as It's parameters.The theme parameter is for specifying the theme (dark or light). If you want the SDK to be in the same theme mode as set in system display settings, you need to pass IDWiseSDKTheme.systemDefault. However, if the OS is in dark mode and you want the SDK to be in light mode (or vice versa), you can pass the appropriate value for the theme parameter.

Possible values for the theme parameter include IDWiseSDKTheme.light,IDWiseSDKTheme.dard and IDWiseSDKTheme.systemDefault.

        
IDWiseSDKTheme.light // to specify light theme mode for SDK
IDWiseSDKTheme.dark // to specify dark theme mode for SDK
IDWiseSDKTheme.systemDefault // to specify the same theme as of operating system

        IDWise.initialize(clientKey: "<YOUR_CLIENT_KEY>",theme: .systemDefault) { error in
                // Deal with error here
                print(error?.message)
        }
        
        IDWise.startDynamicJourney(journeyDefinitionId: "<FLOW_ID>", referenceNumber: "<YOUR_REFERENCE_NO>", locale: "en", journeyDelegate: self, stepDelegate: self)
        

This will make IDWise SDK start a journey and make it the current journey. You can next start steps of this journey and guide the user through completing the necessary steps in the desired order.

This method takes following parameters:

  • journeyDefinitionId: (aka Flow ID) This is a unique identifier that identifies your journey flow. IDWise shares this with you when you register to use IDWise system.
  • referenceNumber: (Optional) This parameter allows you to attach a unique identifier (such as a reference number) with the user undergoing the current journey. It's beneficial for connecting the journey to the user and/or the application that initiated it. You will receive this reference number in the webhook request.
  • locale (Optional) : Language code of the language to be used to display the journey user interface. This is either an ISO 639-1 (2-letter for example en) or IETF BCP 47 (2-letter plus extended language specified for example zh-HK or zh-CN)
  • journeyDelegate: This parameter is used to provide a set of event handlers to handle the different events that are triggered from IDWise SDK. These events indicate the lifetime of a journey and provide oppurtunity for your application to react to certain journey events.
  • stepDelegate: This parameter is used to provide a set of event handlers to handle the different events that are triggered from IDWise SDK. These events indicate the lifetime of a verification step and provide oppurtunity for your application to react to certain step events.

Starting the Steps

After calling startJourney method and subsequently when JourneyStarted method is triggered successfully, you can call the IDWise.startStep method.

IDWise.startStep(stepId: String)

IDWise.startStep method takes the following parameter:

stepId: ID of the step you want to start. (Will be provided by IDWise for each step)

You can also pass a PDF or an Image as Data and for that you can use following method named startStepFromFileUpload.
Important Note: Size of the Data should be less then or equal to 4Mb. Following is an example

   IDWise.startStepFromFileUpload(stepId: String, data: Data)

IDWise.startStepFromFileUpload method takes the following parameter:

stepId: ID of the step you want to start. (Will be provided by IDWise for each step)

data: Data representation of an image file or a PDF file ( Data bytes must be less than or equal to 4Mb )

The methods in IDWiseStepDelegate will be triggered as step is handled and processed

Skipping the Step

When onJourneyStarted(...)or onJourneyResumed(...) are triggered successfully, you can call the IDWise.skipStep(...) to skip any verification Step.

IDWise.skipStep(stepId: String)

This method takes only one parameter:

  • stepId : ID of the step you want to skip. (Will be provided by IDWise for each step)

The step events (provided in IDWiseSDKStepCallback parameter provided to startDynamicJourney or resumeDynamicJourney method) will be triggered as step is skipped.

Step Callbacks

We can implement the protocol IDWiseSDKStepDelegate as an extension on the ViewController same way as above to recieve the step events:


extension ViewController:IDWiseSDKStepDelegate {
    
    // This method will be triggered when user has captured the image/selfie from the camera
    func onStepCaptured(stepId: Int, capturedImage: UIImage) {
        // An example of showing custom UI
        LoadingView.show()
    }
    
    //This method will be triggered when Image processing is completed at the backend.
    //stepId will be the Id of the step that is just completed
    func onStepResult(stepId: Int,stepResult: StepResult?) {
        // An example of showing custom UI
        LoadingView.hide()
        if let result = stepResult {
          print(result.document?.documentType)
        }
    }
  
    // This method will be triggered when user press the back button and IDWise UI is dimissed and control is back with HostingApp
    func onStepCancelled(stepId: String) {
    }
  
    // This method will be triggered when hosting app calls IDWise.skipStep and step is skipped successfully
    func onStepSkipped(stepId: String) {
    }
  
    func onStepConfirmed(stepId: String) {
    }

}
  • onStepCaptured : This handler will be triggered when user has captured the document or selfie. Control will be returned to your application by this point and you can show any UI or run business logic to guide the user through the rest of the journey. At this point the captured image will have started uploading to backend in the background but would have not finished processing. This method is triggered up to two times (if document has two sides).

  • onStepResult : This handler will be triggered when step has finished processing. stepResult will contain information about the corresponding step. Your application can show any UI or can perform any business logic in this method. This method is always triggered only once per step even If document has two sides.

  • onStepCancelled : This handler will be triggered when step is cancelled by the user. This can happen when user presses back button until IDWise UI is dismissed and control is back with hosting application.

  • onStepSkipped : This handler will be triggered when hosting app will call IDWise.skipStep(stepId:).This callback will only be called If step is skipped successfully.

From stepResult variable in onStepResult(...) callback, you can receive the extracted fields. And if the validation is failed, you can get the failure code as stepResult.failureReasonCode

StepResult contains following information

FieldTypeDescription
recognitionDocumentRecognitionDocument recognition information
extractedFieldsMap of String and FieldValueInformation extracted from the document such as Name and Birth Date
hasPassedRulesBooleanWhether the step passes the validity checks
isConcludedBooleanWhether the user can still retry the step or not
statusStringProcessing status one of (In Progress, Submitted, Not Submitted)
errorUserFeedbackCodeStringA code that can be used to indicate the error. All the error feedback codes can be found here.
errorUserFeedbackDetailsStringdetails for the error message directed at the user, providing feedback in case an error occurs during the step.
errorUserFeedbackTitleStringA title for the error message directed at the user, providing feedback in case an error occurs during the step.
nfcResultNFCResultResult from NFC chip reading

The DocumentRecognition object contains the following information related to the scanned document.

FieldTypeDescription
issuingCountryCodeStringCountry of issue as ISO 3166-1 alpha-3 country code
issuingCountryNameStringName of country of issue
documentTypeStringType of the Document, either a Identity Card, Passport, Commercial Licence, Driving Licence, Practice Permit, Residence Permit, Utility Bill, Vehicle Licence, Vaccination Card, Work Permit, Car Registration, Travel Document, Car Ownership, Visa, Vehicle Registration, Proof of Address, Other Forms, Insurance Certificate, Birth Certificate, Registration Certificate, Tax Document, National Insurance Document, Military ID, Voter Card, Archive Only.

The NFCResult object contains the following data extracted from the Document via reading the NFC chip

FieldTypeDescription
facePhotoBitmapImage of the user which is extracted from NFC chip scanning
extractedFieldsMap of String and FieldValueInformation extracted from the NFC chip scanning

All extractedFields from the NFC can be found here

Finishing the Journey

You need to call this IDWise.finishDynamicJourney() method to mark the journey complete. This method will mark the current dynamic journey as finished. The method will throw error through onError(error: IDWiseSDKError) if anything goes wrong.

Get Summary of the Verification Journey

You can call this method IDWise.getJourneySummary(callback: @escaping ((JourneySummary?,IDWiseSDKError?)->())) method anytime to get status of your journey. You will receive a callback with JourneySummary or an IDWiseSDKError in case anything fails at server side or in authentication.

IDWise.getJourneySummary(callback: { summary,error in

})

JourneySummary contains the following information


FieldTypeDescription
journeyIdStringA unique identifier for the user journey.
isCompletedBooleanA boolean field that indicates if the journey is completed or not.
stepSummariesList of StepSummaryAn array of objects that detail the steps the user has gone through in the journey. Each object in this array contains a definition and a result.
journeyResultJourneyResultResult and Status of the verification Journey as described below

StepSummary contains the following information

FieldTypeDescription
definitionStepDefinitionAn object that describes the step.
resultStepResultAn object that contains the result of the step.

StepDefinition contains the following information

FieldTypeDescription
step_idIntAn identifier for the step within the journey.

JourneyResult contains the following information

FieldTypeDescription
completedStepsIntNumber of completed steps in the journey
interimRuleAssessmentInterimRuleAssessmentEnum for the combined Interim rules assessment result [Passed, Failed]
interimRuleDetailsHashMap<String, RuleDetail>Hashmap of all the Rules Assessment Results applicable

RuleDetail contains the following information

FieldTypeDescription
nameStringName of the Rule
resultResult of the Rule AssessmentEnum for the combined Interim rules assessment result [Passed, Failed, CouldNotApply]

Error Feedbacks

You can access the table of error feedbacks, which includes descriptions for each of the feedback codes on here

Resuming a journey

You can resume the exiting, incompleted journey at any time. Following is the sample to Resume an existing journey.

IDWise.resumeDynamicJourney(journeyDefinitionId: "<YOUR_CUSTOMER_ID>",journeyId: "<JOURNEY_ID>",locale: "en", journeyDelegate: self, stepDelegate: self)

This method takes following parameters:

  • journeyDefinitionId: Specifies the journey definition (aka template) to base this new journey on. Journey definitions are created based on your requirements and specify what documents and biometrics to collect from the user and in what order. JourneyDefinitionId is shared with you by IDWise team as part of your use-case and requirements discussions.
  • journeyId: journeyId of the journey you want to resume. which you got in onJourneyStarted callback when you started the journey first time.
  • locale (Optional) : Language code of the language to be used to display the journey user interface. This is either an ISO 639-1 (2-letter for example en) or IETF BCP 47 (2-letter plus extended language specified for example zh-HK or zh-CN)
  • journeyDelegate: This parameter is used to provide a set of event handlers to handle the different events that are triggered from IDWise SDK. These events indicate the lifetime of a journey and provide oppurtunity for your application to react to certain journey events.
  • stepDelegate: This parameter is used to provide a set of event handlers to handle the different events that are triggered from IDWise SDK. These events indicate the lifetime of a verification step and provide oppurtunity for your application to react to certain step events.

Unloading the SDK

You can unload the SDK when it is no longer required to free up the resources

IDWise.unloadSDK()

πŸ“˜

Sample Project

You can find the sample project for a complete iOS Integration in dynamic mode.

Managing Device Orientation

IDWise SDK only supports portrait orientation for Its screens. If you are supporting multiple orientations other than portrait then you either need to lock your full app to portrait or you can use our helper class that locks the orientation for our SDK screens only.

  1. You need to add following struct in your code.
struct AppUtility {

    static func lockOrientation(_ orientation: UIInterfaceOrientationMask) {
    
        if let delegate = UIApplication.shared.delegate as? AppDelegate {
            delegate.orientationLock = orientation
        }
    }

    /// OPTIONAL Added method to adjust lock and rotate to the desired orientation
    static func lockOrientation(_ orientation: UIInterfaceOrientationMask, andRotateTo rotateOrientation:UIInterfaceOrientation) {
   
        self.lockOrientation(orientation)
    
        UIDevice.current.setValue(rotateOrientation.rawValue, forKey: "orientation")
        UINavigationController.attemptRotationToDeviceOrientation()
    }

}
  1. You need to add following code in your AppDelegate.swift class.
 /// set orientations you want to be allowed in this property by default
    var orientationLock = UIInterfaceOrientationMask.all

    func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
            return self.orientationLock
    }
  1. Now before starting Initialising and starting IDWise journey, you can lock the orientation using follow code.
 AppUtility.lockOrientation(.portrait)
  1. After IDWise journey is finished or cancelled, you can unlock the orientation again so It can again support multiple orientations for your application screens.
extension ViewController:IDWiseSDKJourneyDelegate {
    func onError(error: IDWiseSDKError) {
       
    }
    
    func JourneyStarted(journeyID: String) {
        
    }

    func onJourneyResumed(journeyID: String) {

    }
  
    func JourneyCancelled() {
       AppUtility.lockOrientation(.all)
    }
  
    func JourneyFinished() {
       AppUtility.lockOrientation(.all)
    }
}

Error Codes

Error CodeError Description
11Invalid/Empty Parameter (Client key is empty or Invalid)
22SDK is not initialized. Please Call IDWise.initialize(:) first
33Wrong API credentials (Client Key) provided
44Empty journeyId is provided to resume journey.
45Provided file size is exceeding the maximum file size
66No step found against provided stepId to start.
70Invalid step Id provided, please provide a valid stepId.
-101An unexpected error occurred while processing the request.Make sure you have Internet connected
-102Network seems to be not connected, Please try again with network connected.
55This method is not supported in this Journey Mode

NFC Extracted Fields

Field Name
Full Name
First Name
Last Name
Birth Date
Expiry Date
Issue Date
Document Number
Issuing Authority
Issuing Country
Issuing Country Code
Machine Readable Zone
Machine Readable Zone Type
Nationality
Nationality Code
Personal Number
Sex

Keep in touch

Please get in touch if you want to make any adjustments or customisations to your users journey.
Please feel free to jump on a chat by visiting our website: <www.idwise.com>