Bio Login with Backend V2
Overview
BioLogin verifies a user by capturing a selfie and uploading it to your backend via Amani services. On iOS, the module renders a UIView you embed in your controller, handles the camera flow, and returns a preview image if needed. The high‑level flow is:
Initialize Amani → receive token and customerId.
Create BioLogin instance and configure it with server, token, customer_id, attempt_id, biologintype.
Start the module → get a UIView to add to your view hierarchy. On completion, upload the captured data via bioLogin.upload
BioLogin supports multiple capture modes via biologintype:
autoSelfie (default) — automatic selfie capture.
poseEstimation — guided head‑pose sequence.
manualSelfie — user captures selfie manually.
Requirements
AmaniSDK 3.4.17 or higher version.
Xcode 13+ (recommended) and Swift.
Camera and microphone permissions configured if required by your chosen mode.
A valid Amani server URL and credentials.
Basic Flow
final class BioLoginViewController: UIViewController {
private let amaniSDK = Amani.sharedInstance
private var bioLogin: BioLogin?
private var bioLoginView: UIView?
private var token: String?
private var customerId: String?
// MARK: - 1) Init Amani (get token & customerId)
private func initAmani() {
let customer = CustomerRequestModel(name: "", email: "", phone: "", idCardNumber: "")
amaniSDK.initAmani(
server: "<YOUR_SERVER_URL>",
token: "<USERNAME>",
customer: customer,
apiVersion: .v2
) { [weak self] result, error in
guard let self = self, error == nil, let result = result else {
print("Amani init error: \(error?.localizedDescription ?? "unknown")")
return
}
self.token = result.token
self.customerId = result.id
}
}
// MARK: - 3) Start BioLogin Module
func startBioLogin() {
let bioLogin = amaniSDK.bioLogin()
self.bioLogin = bioLogin
bioLogin.setParams(
server: "<YOUR_SERVER_URL>",
token: token,
customer_id: customerId,
attempt_id: "3",
biologintype: .autoSelfie // or .manualSelfie / .poseEstimation
)
DispatchQueue.main.async { [weak self] in
guard let self = self else { return }
do {
let bioView = try bioLogin.start { [weak self] _ in
self?.uploadBioLogin()
}
guard let bioView = bioView else {
print("BioLogin.start returned nil view")
return
}
bioView.frame = self.view.bounds
self.view.addSubview(bioView)
self.bioLoginView = bioView
} catch {
print("BioLogin.start error: \(error)")
}
}
}
// MARK: - 3) Upload result
private func uploadBioLogin() {
guard let bioLogin = bioLogin else { return }
bioLogin.upload { [weak self] isSuccess in
DispatchQueue.main.async {
print("Upload status: \(isSuccess == true ? "success" : "failed")")
bioLoginView?.removeFromSuperview()
bioLoginView = nil
bioLogin = nil
}
}
}
}