# How to Add Photo ID Capture and Face Matching to Your Web or Mobile Application

{% hint style="warning" %}
Please note: this guide applies to the non-container flow only.
{% endhint %}

{% hint style="info" %}
Please note that the **Oz Liveness Mobile SDK does not include a user interface for scanning official documents**. You may need to explore alternative SDKs that offer that functionality or implement it on your own. Web SDK does include a simple photo ID capture screen.
{% endhint %}

This guide describes the steps needed to add face matching to your liveness check.&#x20;

By this time you should have already implemented liveness video recording and liveness check. If not, please refer to these guides:

* [Integration of Oz Liveness Web SDK](https://doc.ozforensics.com/oz-knowledge/general/integration-quick-start-guides/server-based-liveness/how-to-integrate-server-based-liveness-into-your-web-application)
* [Integration of Oz Liveness Mobile SDK](https://doc.ozforensics.com/oz-knowledge/general/integration-quick-start-guides/server-based-liveness/how-to-integrate-server-based-liveness-into-your-mobile-application)

<figure><img src="https://2532558063-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F5g6dgsxRbyrCvB0uAf8f%2Fuploads%2FkO9yiuogGe1hp2LSVVIa%2Ffacematching2-scheme-v8.drawio.png?alt=media&#x26;token=58076807-8a9b-450c-a7ff-0ba662b8179e" alt=""><figcaption></figcaption></figure>

### Adding Photo ID Capture Step to Web SDK

Simply add `photo_id_front` to the list of actions for the plugin, e.g.,

```php
OzLiveness.open({
  session_token,
  lang: 'en',
  action: [
    'photo_id_front', 
    'video_selfie_blank'
  ],
  ...
});
```

### Adding Face Matching to Android SDK

For the purpose of this guide, it is assumed that your reference photo (e.g., front side of an ID) is stored on the device as *reference.jpg*.

Modify the code that runs the analysis as follows:

{% tabs %}
{% tab title="Kotlin" %}

```kotlin
private fun analyzeMedia(mediaList: List<OzAbstractMedia>) {

    val refFile = File(context.filesDir, "reference.jpg")
    val refMedia = OzAbstractMedia.OzDocumentPhoto(
        OzMediaTag.PhotoIdFront , // OzMediaTag.PhotoSelfie for a non-ID photo
        refFile.absolutePath
    )

    AnalysisRequest.Builder()
        .addAnalysis(Analysis(Analysis.Type.QUALITY, Analysis.Mode.SERVER_BASED, mediaList))
        .addAnalysis(Analysis(Analysis.Type.BIOMETRY, Analysis.Mode.SERVER_BASED, mediaList + refMedia))
        .build()
        .run(object : AnalysisRequest.AnalysisListener {
            override fun onSuccess(result: List<OzAnalysisResult>) {
                result.forEach { 
                    println(it.resolution.name)
                    println(it.folderId)
                }
            }
            override fun onError(error: OzException) {
                error.printStackTrace()
            }
        })
} 
```

{% endtab %}

{% tab title="Java" %}

```java
private void analyzeMedia(List<OzAbstractMedia> mediaList) {
    File refFile = new File(context.getFilesDir(), "reference.jpg");
    OzAbstractMedia refMedia = new OzAbstractMedia.OzDocumentPhoto(
            OzMediaTag.PhotoIdFront , // OzMediaTag.PhotoSelfie for a non-ID photo
            refFile.getAbsolutePath()
    );
    ArrayList<OzAbstractMedia> mediaWithReferencePhoto = new ArrayList<>(mediaList);
    mediaWithReferencePhoto.add(refMedia);
    new AnalysisRequest.Builder()
            .addAnalysis(new Analysis(Analysis.Type.QUALITY, Analysis.Mode.SERVER_BASED, mediaList, Collections.emptyMap()))
            .addAnalysis(new Analysis(Analysis.Type.BIOMETRY, Analysis.Mode.SERVER_BASED, mediaWithReferencePhoto, Collections.emptyMap()))
            .build()
            .run(new AnalysisRequest.AnalysisListener() {
                @Override public void onStatusChange(@NonNull AnalysisRequest.AnalysisStatus analysisStatus) {}
                @Override
                public void onSuccess(@NonNull List<OzAnalysisResult> list) {
                    String folderId = list.get(0).getFolderId();
                }
                @Override
                public void onError(@NonNull OzException e) { e.printStackTrace(); }
    });
}
```

{% endtab %}
{% endtabs %}

For on-device analyses, you can change the analysis mode from `Analysis.Mode.SERVER_BASED` to `Analysis.Mode.ON_DEVICE`

Check also the Android [sample app](https://gitlab.com/oz-forensics/oz-liveness-android) source code.

### Adding Face Matching to iOS SDK

For the purpose of this guide, it is assumed that your reference photo (e.g., front side of an ID) is stored on the device as *reference.jpg*.

Modify the code that runs the analysis as follows:

```swift
let imageURL = URL(fileURLWithPath: NSTemporaryDirectory())
    .appendingPathComponent("reference.jpg")

let refMedia = OZMedia.init(movement: .selfie,
                   mediaType: .movement,
                   metaData: nil,
                   videoURL: nil,
                   bestShotURL: imageUrl,
                   preferredMediaURL: nil,
                   timestamp: Date())
   
var mediaBiometry = [OZMedia]()
mediaBiometry.append(refMedia)
mediaBiometry.append(contentsOf: mediaToAnalyze)
let analysisRequest = AnalysisRequestBuilder()
let analysisBiometry = Analysis.init(media: mediaBiometry, type: .biometry, mode: .serverBased)
let analysisQuality = Analysis.init(media: mediaToAnalyze, type: .quality, mode: .serverBased)
analysisRequest.addAnalysis(analysisBiometry)
analysisRequest.addAnalysis(analysisQuality)
analysisRequest.uploadMedia(mediaBiometry)
analysisRequest.run(
    scenarioStateHandler: { state in }, // scenario steps progress handler
    uploadProgressHandler: { (progress) in } // file upload progress handler
) { (analysisResults : [OzAnalysisResult], error) in
    // receive and handle analyses results here
    for result in analysisResults {
        print(result.resolution)
        print(result.folderID)
    }
}
```

For on-device analyses, you can change the analysis mode from `mode: .serverBased` to `mode: .onDevice`

Check also the iOS [sample app](https://gitlab.com/oz-forensics/public/oz-liveness-ios-sample/-/tree/main) source code.

### Final notes for all SDKs

You will be able to access your media and analysis results in Web UI via browser or programmatically via API.

Oz API methods as well as Mobile and Web SDK methods can be combined with great flexibility. Explore the options available in the [Developer Guide](https://doc.ozforensics.com/oz-knowledge/guides/developer-guide) section.

<br>
