DocumentDetector v9.x or above

Current Version





Deployment InfoVersion

iOS Target






Required permissions

In the info.plist file, add the permissions below:




Privacy - Camera Usage Description

To capture the document photo(s)

No, only required in camera capture stream

Privacy - Photo Library Usage Description

To perform the gallery opening.

No, required only in the upload stream

SDK size

The SDK will add approximately 8 MB to your final app.


In your Podfile, specify the reference to our framework. Replacing <version> with the current version:

target 'your-project' do

  pod 'DocumentDetector', '<version>'

Supported documents

Currently supported documents are:

Document.RG_FRONT, // front of RG (where the photo is located)
Document.RG_BACK, // back of RG
Document.RG_FULL, // RG opened (showing front and back together)
Document.CNH_FRONT, // front of CNH (where the photo is located)
Document.CNH_BACK, // back of CNH
Document.CNH_FULL, // CNH opened (showing front and back together)
Document.CRLV, // CRLV
Document.RNE_FRONT, // front of RNE or RNM
Document.RNE_BACK, // back of RNE or RNM
Document.PASSPORT, // passport (showing the photo and data)
Document.CTPS_FRONT, // front of CTPS (where the photo is located)
Document.CTPS_BACK, // back of CTPS
Document.ANY; // allows you to send any type of document, all those mentioned above, including any other document, as there are no typifications

Instantiating the SDK

First, instantiate an object of type DocumentDetectorSdk:

let documentDetector = DocumentDetectorSdk.CafBuilder(mobileToken: "mobileToken")
    // see table bellow

DocumentDetector Options



String mobileToken

Usage token associated with your CAF account.


.setDocumentCaptureFlow(flow :[DocumentDetectorStep])

Sets the document capture flow, as explained here.


.setPeopleId(peopleId: String?)

Identifier of the user for the purpose of identifying a fraudulent profile.

No, only used for analytics.

.setAnalyticsSettings(useAnalytics: Bool)

Enables/disables data collection for analytics.

No, the default is true.

.setPopupSettings(show: Bool)

Change the setting of the inflated popups before each document.

No, the default is true.

.setLayout(layout: DocumentDetectorLayout)

It allows you to change some of the SDK's layout attributes, such as buttons, colors and fonts. See the available options and an example here.


.setOverlay(overlay: DocumentOverlayView)

It allows you to access the components and get UI updates for more complete layout customizations. See this page for more details.



Change the default network settings.

No. The default is 60 (seconds).

.setLuminositySensorSettings(luminosityThreshold :Float?)

Defines threshold between acceptable/unacceptable ambient brightness. The threshold of this sensor is a number ranging from negative to positive.

No. The default setting is -3.

.setOrientationSensorSettings(orientationThreshold: Double?)

Defines threshold between correct/incorrect device orientation. Higher the value more flexible it will be. The threshold of this sensor is the acceleration of the device.

No. The default setting is 0.3.

.setStabilitySensorSettings(stabilityThreshold: Double?)

Changes the default settings of the stability sensor. The threshold of this sensor is in the range of the last two accelerations collected from the device.

No. The default setting is 0.3.

.setProxySettings(proxySettings: CafProxySettings?)

Sets the proxy settings, as explained here.

No. The default is null.

.showPreview(_ show: Bool, title: String?, subtitle: String?, confirmLabel: String?, retryLabel: String?)

Enables/disables the capture preview. If show has true, after each capture, the SDK provides a screen for the user to approve or make the capture again. For the remaining parameters, enter nil to use the default value or a String for a custom text.

No. The default is false.


Allows customizing messages displayed in the feedback label during the capture and analysis process.See the available attributes here.


.setCompressSettings(compressionQuality: CGFloat)

Allows you to configure the quality in the compression process. By default, all captures go through compression. The method expects values between 0.8 and 1.0 as a parameter, where 1.0 is the best quality compression.

No. The default is 0.9.

.setManualCaptureSettings(enable: Bool, time: TimeInterval)

Enables/disables manual capture. The time parameter sets the time for the capture mode to be enabled.

No. The default is disabled.

.enableMultiLanguage(_ enable: Bool)

Enables/disables multi-language support.

No. The default is enabled.

.setGetImageUrlExpireTime(expireTime: String)

Sets how long the image URL will last on the server until it is expired. Expect to receive a time interval between "30m" to "30d".


  • "30m": To set minutes only

  • "24h": To set only hour(s)

  • "1h 10m": To set hour(s) and minute(s)

  • "10d": To set day(s)

No. The default is 3h.

.setCurrentStepDoneDelay(currentStepDoneDelay: TimeInterval)

Delay the activity after the completion of each step. This method can be used to display a success message on the screen itself after the capture, for example.

No. The default is false.

.setUploadSettings(uploadSettings CafUploadSettings)

Sets the settings for uploading documents. By enabling this option, the SDK flow will prompt the user to upload the document files instead of capturing them with the device's camera. This option also includes document type and quality checks. See how to set it here.

No. By default this option is disabled.

.setResolutionSettings(resolution: CafResolution)

Allows you to set the capture resolution. The method takes as parameter a Resolution that has the following options:

  • FULL_HD (1920 x 1080)

  • ULTRA_HD (3840 x 2160)

No. The default is FULL_HD.

.setAllowedPassportList(passportList: [CafCountryCodes])

Enables the option to allow passports from only a certain issuing country, or, a list of countries. See the complete list at: ISO 3166-1 alpha-3.


  • .setAllowedPassportList(passportList: [CafCountryCodes.BRA])

No. Passports issued by any country are accepted by default.


To create a capture flow, you will need to create an array of DocumentDetectorStep, where each element will be a capture step. To construct each DocumentDetectorStep object, you can enter the following elements:



document: Document

Identifies which document you want to capture in the respective step.


stepLabel: String?

Text to be displayed at the bottom of the layout.

No. There is a pattern per Document type.

illustration: UIImage?

Illustration to be shown in the popup before the capture.

No. There is a pattern per Document type.

showStepLabel: Bool?

Present the text to be displayed at the top of the layout.

No. the default is true.

Customizing layout

You can customize the layout by creating an object of type DocumentDetectorLayout and passing it as a parameter in setLayout(). The DocumentDetectorLayout elements are:




closeButtonImage: UIImage

Icon of close SDK button.


closeButtonColor: UIColor

Color of close SDK button.


closeButtonSize: CGFloat

Size of close SDK button.


closeButtonContentMode: UIView.ContentMode

Content mode of close SDK button.


font: String

Font of all SDK texts.


primaryColor: UIColor

Principal color, applied to buttons.


feedbackColors: DocumentFeedbackColors

Colors of the feedback area. All colors have an opacity of 0.4 by default.



let layout = DocumentDetectorLayout()
layout.closeButtonImage = UIImage(named: "my_close_image")
layout.closeButtonColor = .green
layout.closeButtonSize = CGFloat(50)
layout.closeButtonContentMode = .scaleAspectFill

layout.font = "my_font"

layout.primaryColor = .blue
layout.feedbackColors = DocumentFeedbackColors(defaultColor: .black, errorColor: .red, successColor: .green)

let documentDetector = DocumentDetectorSdk.CafBuilder(mobileToken: "mobileToken")
    .setDocumentCaptureFlow(flow: [DocumentDetectorStep(document: Document.CNH_FRONT), DocumentDetectorStep(document: Document.CNH_BACK)])
    .setLayout(layout: layout)


    waitMessage: String?, 
    fitTheDocumentMessage: String?, 
    verifyingQualityMessage: String?, 
    lowQualityDocumentMessage: String?, 
    uploadingImageMessage: String?, 
    popupDocumentSubtitleMessage: String?, 
    unsupportedDocumentMessage: String?, 
    wrongDocumentMessage: String?, 
    sensorLuminosityMessage: String?, 
    sensorOrientationMessage: String?, 
    sensorStabilityMessage: String?, 
    predictorScanDocumentMessage: String?, 
    predictorGetCloserMessage: String?, 
    predictorCentralizeMessage: String?,
    predictorMoveAwayMessage: String?, 
    predictorAlignDocumentMessage: String?, 
    predictorTurnDocumentMessage: String?, 
    predictorCapturedMessage: String?


Default Value

waitMessage: String

Message displayed when SDK is in the process of opening.

"Please Wait…"

fitTheDocumentMessage: String

Message advising to fit the document to the mask.

"Fit the document on the markup"

verifyingQualityMessage: String

Message displayed when the SDK makes a request to the backend, verifying quality.

"Checking Quality…"

lowQualityDocumentMessage: String

Message displayed when the quality of the capture fails.

"Ops, could not read the information. Please try again"

uploadingImageMessage: String

Message displayed when there is no quality check and the capture is being saved on the servers.

"Sending Image…"

popupDocumentSubtitleMessage: String

Text displayed in the step initialization popup.

"Dispose the document in a desk, centralize it on the markup and hold the automatic capture."

unsupportedDocumentMessage: String

Message displayed when a unexpected type of document is displayed for capture.

"Ops, it seems that this document is not supported. Contact us!"

wrongDocumentMessage: String

Message displayed when the document is displayed in a different stream than expected.

"Oops, this document is not the %@"

sensorLuminosityMessage: String

Message displayed when the brightness threshold is lower than expected.

"Area near you is too dark"

sensorOrientationMessage: String

Message displayed when the orientation threshold is lower than expected.

"The device is not on the horizontal"

sensorStabilityMessage: String

Message displayed when the orientation threshold is lower than expected.

"Keep the device still"

predictorScanDocumentMessage: String

Message displayed to request a document to be present on the camera.

"Scan a document"

predictorGetCloserMessage: String

Message displayed to request to get closer to the document.

"Get closer to the document"

predictorCentralizeMessage: String

Message displayed to request to center the document.

"Center the document"

predictorMoveAwayMessage: String

Message displayed to request to move away from the document.

"Move away from the document"

predictorAlignDocumentMessage: String

Message displayed to request to align the document.

"Align the document"

predictorTurnDocumentMessage: String

Message displayed to request to turn document 90 degrees.

"Turn the document 90 degrees"

predictorCapturedMessage: String

Message displayed to alert that the document was captured.

"Document captured"


To activate the document upload functionality it is necessary to instantiate an object of type CafUploadSettings() and set its parameters:




Enables/disables this feature.

No. The default is true.


Enables/disables file compression before uploading.

No. The default is true.


Defines the file format(s) that will be accepted for upload.

No. By default .PDF, .JPEG and .PNG are accepted.


Sets the maximum KB limit of the file to upload.

No. The default limit is 10000 KB (10MB).

Currently, the supported file formats are:

public enum FileFormat: String {
    case png
    case jpeg
    case pdf

Getting the result

To get the result, you must implement the DocumentDetectorControllerDelegate delegate in your controller:

class YouController: UIViewController, DocumentDetectorControllerDelegate{
    // MARK: - Document Detection Delegates
    func documentDetectionController(_ scanner: DocumentDetectorController, didFinishWithResults results: DocumentDetectorResult) {
        //Called when the process was successfully executed
        //The result variable contains the data obtained
    func documentDetectionControllerDidCancel(_ scanner: DocumentDetectorController) {
        // Called when the user cancel
    func documentDetectionController(_ scanner: DocumentDetectorController, didFailWithError error: DocumentDetectorFailure) {
        //Called when the process terminate with an error
        //The error variable contains info about error

After creating the DocumentDetector object, start the DocumentDetectorController by passing this object as a parameter in the constructor:

let scannerVC = DocumentDetectorController(documentDetector: documentDetector)
scannerVC.documentDetectorDelegate = self
present(scannerVC, animated: true, completion: nil)



Can it be null?


The array with the respective captures of the parameterized documents.

Yes, in case of error.

type: String

The class of the read document stream. This parameter is useful in an integration with our OCR route. The existing types are: ["blank", "cnh", "cnh_new", "generic", "rg", "rg_new", "rne", "rnm", "ctps", "passport", "crlv", "crlv_new", "cin"].

Yes, in case of error.

trackingId: String?

Identifier of this run on our servers. If possible, save this field and send it along to our API. This way we will have more data about how the user behaved during the execution.

Yes, if the user sets useAnalytics = false or the analytics calls do not work.



Can it be null?

image: UIImage

Document image.


imageUrl: String

URL of the document on Caf's server. This URL has an expiry time, which can be set with the setGetImageUrlExpireTime method.


label: String

Label of the respective document within the following possibilities: ["blank", "cnh_back", "cnh_front", "cnh_full", "new_cnh_back", "new_cnh_front", "new_cnh_full", "crlv", "crlv_new", "generic", "rg_back", "rg_front", "rg_full", "rg_new_back", "rg_new_front", "rg_new_full", "rne_back", "rne_front", "rnm_back", "rnm_front", "ctps_back", "ctps_front", "passport", "cin_front", "cin_back"].


quality: Double

Quality inferred by the document quality algorithm. Varies between 0 and 5.



Superclass that leads to the SDK shutdown. To find out what the reason was, find out which object class has the isKindOfClass() method, equivalent to instanceof in Java and is in Dart:





The token entered is not valid for the corresponding product.

Parameterize "test123" as token in the SDK builder.


You are missing some mandatory permission to run the SDK.

Start DocumentDetector without camera permission granted.


Internet connection failure.

User was without internet during facematch in FaceAuthenticator.


When an SDK request receives a status code of failure.

In theory, it shouldn't happen. If it does, let us know!

Last updated


2023 © Caf. - All rights reserved