Skip to main content

Quick Setup

After following the install instructions you are ready to launch the SDK. The overall process involves configuring your scanning options, creating an SDK instance, presenting the scanning UI, and listening for results.

The quick setup will go over each of these steps using SwiftUI and UIKit.

Configuration​

This configuration section describes how to set up the DocumentScannerConfig for customizing the document scanning experience, to do so, follow these steps:

Create a DocumentScannerConfig to customize scanning:

  • autoCaptureToggleConfig: Controls auto-capture UI.
    • .show: Always show auto-capture toggle.
    • .hide: Hide auto-capture toggle.
    • .showDelayed(durationMs: Int): Show toggle after a delay (milliseconds).
  • documentSide: Which side to scan.
    • .front
    • .back
  • documentType: Type of document.
    • .unknown
    • .passport
  • mrzRequired: Whether auto-capture waits for a complete machine readable zone (MRZ) read. Defaults to false.
    • When true, auto-capture is withheld until the MRZ yields all three of documentNumber, dateOfBirth, and expiryDate — the fields needed to derive a Basic Access Control (BAC) key for NFC chip reads. There is no timeout.
    • This gate applies to auto-capture only. Manual capture (the shutter button) always bypasses it, and does not read the MRZ, so its mrz is always nil.
    • When false (the default), auto-capture is never held back for the MRZ. An MRZ read is still attempted on every auto-capture, so its mrz may be fully populated, partially populated, or nil.

Example:

import Document

let config = DocumentScannerConfig(
autoCaptureToggleConfig: .showDelayed(durationMs: 10_000),
documentSide: .front,
documentType: .passport
)

Creating an Instance​

Instantiate the SDK with your configuration:

let sdk = DocumentSDK(documentScannerConfig: config)

Displaying the SDK Content​

SwiftUI​

Present the SDK's main view in your SwiftUI hierarchy:

struct ContentView: View {
@StateObject var sdk = DocumentSDK(documentScannerConfig: config)

var body: some View {
sdk.mainView
}
}

UIKit​

Host the SwiftUI view in a UIHostingController:

import SwiftUI
import Document

let sdk = DocumentSDK(documentScannerConfig: config)
let hostingController = UIHostingController(rootView: sdk.mainView)
present(hostingController, animated: true)

Listening for Result Changes​

This section describes how to listen for document scanning results using either SwiftUI or UIKit so you can handle the results accordingly.

SwiftUI​

Observe the documentScannerResult property:

struct ResultView: View {
@EnvironmentObject var sdk: DocumentSDK

var body: some View {
if let result = sdk.documentScannerResult {
// Handle result
}
}
}

You can also use it with onReceive to react to changes and for example show an alert or navigate to a different view:

var body: some View {
NavigationView {
ZStack {
documentSDK.mainView
if let result = documentSDK.documentScannerResult?.result {
NavigationLink(
destination: ResultsScreenView(
result: result,
metadata: documentSDK.documentScannerResult?.metadata
),
isActive: $showResults
) {
EmptyView()
}
}
}
// Use onReceive to observe changes
.onReceive(documentSDK.$documentScannerResult) { newValue in
showResults = newValue != nil
}
}
}

UIKit​

Set the delegate and implement the protocol:

class MyViewController: UIViewController, DocumentSDKDelegate {
let sdk = DocumentSDK(documentScannerConfig: config)

override func viewDidLoad() {
super.viewDidLoad()
sdk.delegate = self
let hostingController = UIHostingController(rootView: sdk.mainView)
addChild(hostingController)
view.addSubview(hostingController.view)
hostingController.didMove(toParent: self)
}

func documentSDK(_ sdk: DocumentSDK, didUpdateResult result: DocumentScannerResult?) {
// Handle result
}
}

Results Structure​

This section describes the structure of the results returned by the document scanner SDK, including an example of how to handle the results.

DocumentScannerResult contains:

  • result: DocumentProcessingState.Result
    • .success(Success)
      • image: DocumentImage
        • image: Data (PNG)
        • width, height, rotation
        • isGood, isSharp, isGlareFree, isAdequateResolution
      • method: .manualCapture or .smartCapture
      • mrz: MRZData? — the machine readable zone data read during capture, or nil when no MRZ was read.
        • documentNumber, dateOfBirth, expiryDate: String?, in raw MRZ yyMMdd format where present.
    • .failure(Failure)
      • message: Error message
      • component: .smartCapture, .camera, .other
      • cause: Optional error
  • metadata: DocumentProcessingMetadata (optional)
    • blurryFrameCount, glareFrameCount, lowResFrameCount, documentBoundaryFrameCount, processedFrameCount
    • captureDuration, lastFrameProcessingDuration
    • hasDisabledAutoCapture

Example result handling:

if let result = sdk.documentScannerResult {
switch result.result {
case .success(let success):
// Access success.image and success.method
if let mrz = success.mrz,
let documentNumber = mrz.documentNumber,
let dateOfBirth = mrz.dateOfBirth,
let expiryDate = mrz.expiryDate {
// OzoneNFCDocumentKey expects raw MRZ yyMMdd dates and a
// `passportNumber` field — Success.mrz already gives both in that
// shape, just under different property names (documentNumber).
let documentKey = OzoneNFCDocumentKey(
passportNumber: documentNumber,
dateOfBirth: dateOfBirth,
expiryDate: expiryDate
)
// Pass documentKey to OzoneNFCReader / OzoneNFCViewController —
// see the OzoneNFC component's Quick Setup for the scanning call.
}
case .failure(let failure):
// Access failure.message and failure.component
}
if let metadata = result.metadata {
// Access frame counts and durations
}
}