Skip to main content
The Swift SDK gives macOS apps Emirates ID reading and fingerprint capture through an idiomatic async/await API (with callback-style overloads, and full Objective-C support).
Prerequisites. To read a card or capture a fingerprint, install the matching macOS desktop service first — mbkyc-pcsc-service for card readers and the vendor service (e.g. mbkyc-suprema-service) for fingerprint. Without them, listSmartcardReaders() / listFingerprintReaders() return empty. See Install services on macOS and Supported devices. Manual-entry verification needs no services.

Download the example

A self-contained CLI. Drop the XCFramework into deps/, fill in the config block, and swift run.

Install

The Swift SDK ships as a signed, notarized XCFramework — there is no Swift Package Manager or CocoaPods distribution. Download the framework from Nexus and link it into your Xcode project.
1

Download the XCFramework

Fetch it from the raw repository (replace repo.client.ae with your proxied host, and 0.5.0 with the current version):
curl -fsSL -u "$NEXUS_USER:$NEXUS_PASSWORD" \
  https://repo.client.ae/repository/mbkyc-raw/mbkyc/swift-sdk/0.5.0/MBKYCSDK.xcframework.zip \
  -o MBKYCSDK.xcframework.zip
unzip MBKYCSDK.xcframework.zip
2

Add it to your project

Drag MBKYCSDK.xcframework into your Xcode target’s Frameworks, Libraries, and Embedded Content, set to Embed & Sign. The C library is statically linked inside the framework — there’s nothing else to add.

Initialize

import MBKYCSDK

let mbkyc = try MBKYC.create(
    baseUrl:       "https://api.client.ae",
    apiKeyId:      "key-id",
    tokenSigner:   myTokenSigner,   // signs request inputs via your backend
    logConfig:     LogConfig(logDir: URL(fileURLWithPath: "/var/log/myapp")),
    httpTimeoutMs: 30_000
)
The API secret never enters the SDK. You pass a TokenSignerDelegate whose sign(signingInput:completion:) routes the input to the holder of the secret (your backend), signs it, and returns the signature. See Authentication.

Register & validate

Register the device once, then validate with the request for your flow:
let readers = try await mbkyc.listSmartcardReaders()

try await mbkyc.registerDevice(name: "lobby-kiosk")   // once per device

let result = try await mbkyc.validate(
    EmiratesIdManual(
        idNumber:       "784-XXXX-XXXXXXX-X",
        documentNumber: "...",
        nationality:    "ARE"
    )
)
print(result.success, result.message)

Validation requests

Each request is a ValidationRequest subclass. Pick the one for the document you’re verifying — see Validation methods for when to use each, and Install services on macOS for the hardware prerequisites.
Manual entry — no hardware required.
EmiratesIdManual(idNumber: "784-XXXX-XXXXXXX-X", documentNumber: "...", nationality: "ARE")
Card read — needs a smart card reader + mbkyc-pcsc-service.
EmiratesIdCard(readerId: reader.id)
+ Fingerprint — pass a fingerprint: to either request above to add a biometric match (needs a fingerprint sensor + its service — see Biometrics).
EmiratesIdCard(readerId: reader.id, fingerprint: fingerprint)
Full initializers (optional params: dateOfBirth, issueDate, expiryDate, fingerprint, clientReferenceId):
  • EmiratesIdManual(idNumber:documentNumber:nationality:dateOfBirth:issueDate:expiryDate:fingerprint:clientReferenceId:)
  • EmiratesIdCard(readerId:cardDipTimeoutMs:fingerprint:clientReferenceId:)
  • PassportManual(passportNumber:passportType:nationality:dateOfBirth:issueDate:expiryDate:clientReferenceId:)
Each async method also has a completion-handler overload — (VerificationResult?, MBKYCError?) -> Void — for codebases that haven’t adopted async/await.

Biometrics

Attach a Fingerprint to an Emirates ID request (EmiratesIdCard or EmiratesIdManual) to also match a fingerprint. You supply a FingerRecommendationDelegate that picks which finger to capture when the SDK asks:
final class MyFingerDelegate: NSObject, FingerRecommendationDelegate {
    func onFingerRecommendation(
        recommendedFingers: [NSNumber],
        completion: @escaping (FingerSelection) -> Void
    ) {
        let finger = recommendedFingers.first
            .flatMap { Finger(rawValue: $0.uint32Value) } ?? .rightIndex
        completion(.recommended(finger))   // or .custom(.leftMiddle) / .cancel()
    }
}

let fingerprint = Fingerprint(
    readerId: scanner.id,
    recommendationDelegate: MyFingerDelegate())

let result = try await mbkyc.validate(
    EmiratesIdCard(readerId: reader.id, fingerprint: fingerprint))
Requires a fingerprint sensor and its desktop service (e.g. mbkyc-suprema-service). Get scanner.id from listFingerprintReaders().

Error handling

All errors are MBKYCError: Error with a typed ErrorCode enum:
do {
    _ = try await mbkyc.validate(request)
} catch let err as MBKYCError {
    print("code=\(err.error.rawValue) message=\(err.localizedDescription)")
    if let detail = err.detail { print("detail:", detail) }
}

Objective-C

NSError *error;
MBKYC *mbkyc = [MBKYC createWithBaseUrl:@"https://api.client.ae"
                              apiKeyId:@"key-id"
                           tokenSigner:myTokenSigner
                             logConfig:logConfig
                         httpTimeoutMs:30000
                          extraHeaders:nil
                                 error:&error];
MBKYC can be used from any queue; hold it for the lifetime of your SDK use.

Full API reference

async/await signatures below; each has a completion-handler overload of the form completion: @escaping (Value?, MBKYCError?) -> Void. Shared types are in Data types.
MethodSignature
Createstatic MBKYC.create(baseUrl:apiKeyId:tokenSigner:logConfig:httpTimeoutMs:extraHeaders:) throws -> MBKYC
List smart card readerslistSmartcardReaders() async throws -> [ReaderInfo]
List fingerprint readerslistFingerprintReaders() async throws -> [ReaderInfo]
Register deviceregisterDevice(name: String) async throws
Check registrationcheckRegistration() async throws -> RegistrationStatus
Validatevalidate(_ request: ValidationRequest) async throws -> VerificationResult
Export logsexportLogs(to url: URL) async throws
Validation requests (ValidationRequest subclasses — see Validation requests above):
EmiratesIdCard(readerId: String, cardDipTimeoutMs: UInt32 = 5_000,
               fingerprint: Fingerprint? = nil, clientReferenceId: String? = nil)
EmiratesIdManual(idNumber: String, documentNumber: String, nationality: String,
                 dateOfBirth: String? = nil, issueDate: String? = nil, expiryDate: String? = nil,
                 fingerprint: Fingerprint? = nil, clientReferenceId: String? = nil)
PassportManual(passportNumber: String, passportType: String, nationality: String,
               dateOfBirth: String? = nil, issueDate: String? = nil, expiryDate: String? = nil,
               clientReferenceId: String? = nil)

Fingerprint(readerId: String, recommendationDelegate: FingerRecommendationDelegate,
            captureTimeoutMs: UInt32 = 10_000)
Cancel by cancelling the enclosing Task. Errors are thrown as MBKYCError.