Integration Documentation(CustomView Mode)
This document explains how to use the core UI component AAIIQACameraWrapperView
Overview
AAIIQACameraWrapperView
is a UIView component that provides essential scanning and photo capture capabilities. You can directly integrate it into your own page, giving you complete control over UI layout and interaction.
Usage Steps
-
Before using, please refer to the integration documentation to incorporate the SDK into your project, as this component is provided by the "AAIGlobalIQASDK" module.
Note you don't need to integrate theAAIGlobalIQAUI
module, asAAIIQACameraWrapperView
is a standalone component that does not depend on the default UI module, which can reduce the package size. -
Import the
AAIGlobalIQASDK
module where you need to useAAIIQACameraWrapperView
.import AAIGlobalIQASDK
-
Init SDK, then set the license.
AAIGlobalIQASDK.initSDK() let result = AAIGlobalIQASDK.setLicenseAndCheck(demoLicenseContent) if result == "SUCCESS" { // License is valid. We can start using AAIIQACameraWrapperView // ... } else { if result == "LICENSE_EXPIRE" { print("LICENSE_EXPIRE: please call your server's api to generate a new license") } else if result == "APPLICATION_ID_NOT_MATCH" { print("APPLICATION_ID_NOT_MATCH: please bind your app's bundle identifier on our cms website, then recall your server's api to generate a new license") } else { print("\(result)") } }
-
Add
AAIIQACameraWrapperView
to your view hierarchy, and configure it as needed. -
Use the
startScanMode(with:delegate:)
method to begin scanning mode, or thestartPhotoMode(with:delegate:)
method to start photo capture mode. -
Implement the
AAIIQACameraWrapperViewAuthDelegate
protocol andAAIIQACameraWrapperViewScanModeDelegate
orAAIIQACameraWrapperViewPhotoModeDelegate
protocol to handle scan or photo capture callback events.
Example
Below is a simple example demonstrating how to use AAIIQACameraWrapperView
for scanning and taking photos. You can find similar sample code in the demo project(CameraViewDemo1/MyCameraDemo1ViewController.swift
), which you may also reference for implementation.
import AAIGlobalIQASDK
class YourViewController: UIViewController {
private var iqaView: AAIIQACameraWrapperView?
private lazy var scanConfig: AAIIQACameraWrapperViewScanConfig = {
let config = AAIIQACameraWrapperViewScanConfig()
config.region = "ID"
config.cardType = .idCard
config.cardSide = .front
config.detectionTimeoutInterval = 20
return config
}()
private lazy var photoConfig: AAIIQACameraWrapperViewPhotoConfig = {
let config = AAIIQACameraWrapperViewPhotoConfig()
config.region = "ID"
config.cardType = .idCard
config.cardSide = .front
return config
}()
override func viewDidLoad() {
super.viewDidLoad()
// Initialize the iqaView
let iqaView = AAIIQACameraWrapperView()
// Add the iqaView to the main view
self.view.addSubview(iqaView)
// Set constraints or frame for the iqaView
iqaView.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
iqaView.topAnchor.constraint(equalTo: self.view.topAnchor, constant: 100),
iqaView.widthAnchor.constraint(equalTo:self.view.widthAnchor, multiplier: 0.9),
// Set the height to maintain a 16:10 aspect ratio (Recommended)
iqaView.heightAnchor.constraint(equalTo:iqaView.widthAnchor, multiplier: 0.625),
iqaView.centerXAnchor.constraint(equalTo: self.view.centerXAnchor)
])
}
override func willTransition(to newCollection: UITraitCollection, with coordinator: UIViewControllerTransitionCoordinator) {
// Notify the iqaView about the orientation change
iqaView?.willTransition(to: UIDevice.current.orientation)
super.willTransition(to: newCollection, with: coordinator)
}
@objc func tapStartScanModeBtnAction() {
// 1. Update the scanning configuration if needed
/*
// e.g., scanConfig.region = "ID"
scanConfig.region = "id"
scanConfig.cardType = .idCard
scanConfig.cardSide = .front
scanConfig.detectionTimeoutInterval = 20
*/
// 2. Start the scanning mode
iqaView?.startScanMode(with: scanConfig, delegate: self)
}
@objc func tapStartPhotoModeBtnAction() {
// 1. Update the photo configuration if needed
/*
// e.g., photoConfig.region = "ID"
photoConfig.region = "id"
photoConfig.cardType = .idCard
photoConfig.cardSide = .front
*/
// 2. Start the photo mode
iqaView?.startPhotoMode(with: photoConfig, delegate: self)
// During photo mode, you can:
// - Take a photo by calling iqaView?.capturePhoto()
// - Retake a photo by calling iqaView?.discardCapturedPhoto()
// - Confirm and use the captured photo by calling iqaView?.useCapturedPhoto()
}
@objc func tapTakePhotoBtnAction() {
iqaView?.capturePhoto()
}
@objc func tapRetakePhotoBtnAction() {
iqaView?.discardCapturedPhoto()
}
func process(result: AAIGlobalIQAResultProtocol) {
// We recommend you to save the eventId for future issue tracking.
let eventId = result.eventId
print("eventId: \(String(describing: eventId))")
if result.success {
// The final output captured card image in base64 format.
// Note that this image data is suitable for uploading to the server as it has been
// appropriately compressed. You can also obtain this image by calling server side api
// 'openapi/face-identity/image-quality-check/v1/query'
let cardImgBase64String = result.cardImgBase64String
// The raw output captured card image without any compression.
// Note that this image is generally used for preview purposes.
// If you want to upload the image to the server, you should use the
// `cardImgBase64String` property.
let cardImg = result.cardImg
// The identifier string that corresponds to the captured card image,
// which can be used to retrieve the image by calling the server side api
// 'openapi/face-identity/image-quality-check/v1/query'.
let idvid = result.idvid
} else {
let errorCode = result.errorCode
let errorMsg = result.errorMsg
print("errorCode: \(errorCode ?? ""), errorMsg: \(String(describing: errorMsg ?? ""))")
}
}
}
// MARK: - AAIIQACameraWrapperViewScanModeDelegate
// Implement the delegate methods to handle scanning events
extension YourViewController: AAIIQACameraWrapperViewScanModeDelegate {
func iqaOnScanStart() {
print("[callback][iqaOnScanStart]")
}
func iqa(onScanWarnCodeChanged warnCode: AAIIQAWarnCode) {
print("[callback][onScanWarn][\(warnCode.rawValue)]")
var stateKey: String?
var msg: String?
switch warnCode {
case .noCard:
stateKey = "no_card"
msg = "No document is detected"
case .tooSmallCard:
stateKey = "too_small_card"
msg = "Document is too small"
case .edgeCross:
stateKey = "iqa_min_gap_ratio"
msg = "The document is incomplete\nplease make sure the document in the center with the edges aligned"
case .cardPoorQuality:
stateKey = "iqa_card_poor_quality"
msg = "Document is too dim/blurred/overexposed"
case .good:
stateKey = "hold_phone"
msg = "Please hold the phone steadily"
case .hasOccluded:
stateKey = "card_has_occluded"
msg = "Please keep your ID card unobstructed"
case .unspecified:
let _ = "";
@unknown default:
fatalError("Unknown AAIIQAWarnCode!")
}
print("[callback][onScanWarn][\(warnCode.rawValue)] stateKey: \(String(describing: stateKey)), msg: \(String(describing: msg))")
}
func iqa(onScanSuccess rawImage: UIImage?) {
print("[callback][onScanSuccess]")
// Note that you should obtain the original scanned image from the `iqa(onScanModeComplete:)` method
}
func iqa(onScanRemainingSecondsChanged remainSeconds: Int, totalSeconds: Int) {
print("[callback][onDetectionRemainTimeChanged: \(remainSeconds)/\(totalSeconds)]")
}
func iqa(onScanModeComplete result: AAIGlobalIQAResultProtocol) {
print("[callback][onScanModeComplete]")
process(result: result)
if result.errorCode == "SCAN_TIMEOUT" {
// Demo: Enter photoMode
self.iqaView?.startPhotoMode(with: photoConfig, delegate: self)
/*
// Demo: Retry scan
self.iqaView?.startScanMode(with: scanConfig, delegate: self)
*/
return;
} else {
// Stop the iqaView after scan mode is complete
self.iqaView?.stopRunning()
}
}
}
// MARK: - AAIIQACameraWrapperViewPhotoModeDelegate
// Implement the delegate methods to handle photo capture events
extension YourViewController: AAIIQACameraWrapperViewPhotoModeDelegate {
func iqaOnPhotoModeStart() {
print("[callback][iqaOnPhotoModeStart]")
}
func iqa(onCapturePhotoDone capturedImage: UIImage?, previewImage: UIImage) {
print("[callback][onCapturePhotoDone]")
// Show the preview image
// You can display the preview image in an UIImageView or any other UI component
}
func iqa(onPhotoModeComplete result: AAIGlobalIQAResultProtocol) {
print("[callback][onPhotoModeComplete]")
process(result: result)
// Stop the iqaView after photo mode is complete
self.iqaView?.stopRunning()
}
}
// MARK: - AAIIQACameraWrapperViewAuthDelegate
// Implement the delegate methods to handle authentication events
extension YourViewController: AAIIQACameraWrapperViewAuthDelegate {
func iqaOnAuthCheckStart() {
print("[callback][iqaOnAuthCheckStart]")
// Generally, you should show a loading view here
}
func iqa(onAuthCheckFinish error: Error?) {
print("[callback][onAuthCheckFinish]")
// Dismiss the loading view here
}
func iqaOnUploadDataStart() {
print("[callback][iqaOnUploadDataStart]")
// Show a loading view to indicate that data is being uploaded
}
func iqa(onUploadDataFinish error: Error?) {
print("[callback][onUploadDataFinish][\(String(describing: error))]")
// Dismiss the loading view here
}
}
Image Warn Code
During scanning mode, the iqa(onScanWarnCodeChanged:)
delegate method will be called to provide real-time feedback on the quality of the scanned image. The following table lists the possible warning codes and their meanings:
Warn Code (Swift) | Warn Code (Objective-C) | Meaning | Suggested prompts |
---|---|---|---|
.noCard | AAIIQAWarnCodeNoCard | No card detected | No document is detected |
.tooSmallCard | AAIIQAWarnCodeTooSmallCard | Card area is too small | Document is too small |
.edgeCross | AAIIQAWarnCodeEdgeCross | Card edges are incomplete | The document is incomplete\nplease make sure the document in the center with the edges aligned |
.cardPoorQuality | AAIIQAWarnCodeCardPoorQuality | Low card quality: Dim/Blurred/Overexposed | Document is too dim/blurred/overexposed |
.hasOccluded | AAIIQAWarnCodeHasOccluded | Card area is occluded | Please keep your ID card unobstructed |
.good | AAIIQAWarnCodeGood | Card quality is acceptable | Please hold the phone steady |
.unspecified | AAIIQAWarnCodeUnspecified | - | - |
Error Code
See Error Codes Table for details about error codes.
Updated about 18 hours ago