iOS Integration
This guide covers the integration of MubeenDeviceSDK into iOS and macOS applications.
The SDK is distributed as a signed, closed-source XCFramework. All entry points are static methods on the Mubeen type:
import MubeenDeviceSDK
Overview
MubeenDeviceSDK gives each device a persistent identifier and sends device fingerprints to Mubeen for risk analysis. The SDK provides:
- Persistent Device ID — A persistent device ID for the device.
- One-way fingerprinting — A fire-and-forget
sendFingerprint()call with automatic background retry. - Risk Signals — Optional jailbreak and behavioral-signal checks.
Requirements
| Requirement | Version |
|---|---|
| iOS | 15.0+ |
| macOS | 12.0+ |
| Swift | 5.10+ |
| Xcode | 15+ |
The SDK is distributed as a signed, closed-source XCFramework.
Installation
Swift Package Manager (recommended)
In Xcode: File → Add Package Dependencies…, enter
https://github.com/mubeen-ai/Mubeen-IOS-SDK-public.git, and pick 2.0.0.
Or in Package.swift:
dependencies: [
.package(url: "https://github.com/mubeen-ai/Mubeen-IOS-SDK-public.git", from: "2.0.0")
]
Quick Start
1. Configure
Call configure once at launch. It ensures the device ID exists and starts the background retry drain.
import MubeenDeviceSDK
try await Mubeen.configure(
MubeenConfig(
apiKey: "public_your_key",
endpoint: URL(string: "https://fp.sa.mubeen.ai")!,
enableJailbreakChecks: true, // default true
logLevel: .warning // .verbose / .debug / .info / .warning / .error / .none
)
)
apiKey and endpoint are required; the rest have defaults, so a minimal setup is:
try await Mubeen.configure(
MubeenConfig(
apiKey: "public_your_key",
endpoint: URL(string: "https://fp.sa.mubeen.ai")!
)
)
configure throws MubeenSDKError.configurationInvalid when apiKey is empty.
2. Read the Device ID
let id = Mubeen.deviceId // device ID, never nil; lazily generated + persisted
- Available immediately, even before
configure().
To wipe and regenerate the ID (e.g. a privacy/GDPR delete request or user logout):
let newId = Mubeen.resetDeviceId() // wipe + regenerate
3. Send a Fingerprint
do {
try await Mubeen.sendFingerprint()
// accepted (2xx) or queued for retry
} catch let error as MubeenSDKError {
// terminal error (e.g. bad apiKey → 401). See error.errorCode.
}
Configuration
MubeenConfig accepts the following parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
apiKey | String | — (required) | Publishable API key (e.g. public_...). Throws configurationInvalid if empty. |
endpoint | URL | — (required) | Fingerprint collection endpoint (e.g. https://fp.sa.mubeen.ai). |
enableJailbreakChecks | Bool | true | Include jailbreak/root detection signals. |
logLevel | LogLevel | .warning | .verbose, .debug, .info, .warning, .error, or .none. |
Device ID
Mubeen.deviceId is a device ID that is lazily generated and persisted the first time it's read:
let id = Mubeen.deviceId // never nil
It is available immediately, even before configure().
Use resetDeviceId() to comply with a privacy/GDPR delete or on logout:
let newId = Mubeen.resetDeviceId() // wipe + regenerate, returns the new ID
Sending Fingerprints
sendFingerprint() is a one-way call: it either succeeds or enqueues for automatic background retry.
try await Mubeen.sendFingerprint()
When to send
Call sendFingerprint() to gather up-to-date data about the device:
- Once when the app is opened — on launch / foreground.
- Once per significant event — such as sign-in, registration, checkout, or any other high-value action you want scored.
// On app launch
try await Mubeen.sendFingerprint()
// Again at each significant event (sign-in, registration, checkout, …)
try await Mubeen.sendFingerprint()
Response handling
| Result | Behavior |
|---|---|
| 2xx (200 / 202 / 204) | Accepted. |
| 400 / 401 / 403 | Throws MubeenSDKError.serverError. |
| 429 / 5xx / offline | Enqueued and retried automatically; the call returns without throwing. |
| SDK disabled remotely | Throws MubeenSDKError.killSwitchActive. |
Because transient failures are queued rather than thrown, a returned call means "accepted or safely queued." Only terminal errors (4xx other than 429, kill switch, invalid configuration) surface as thrown MubeenSDKErrors.
Observability (optional)
Implement MubeenSDKDelegate to observe request/response activity. Callbacks are dispatched on the MainActor and never expose request or response bodies.
final class Monitor: MubeenSDKDelegate {
func mubeenSDKDidSendRequest(path: String, bodySize: Int) { }
func mubeenSDKDidReceiveResponse(path: String, statusCode: Int, durationMs: Int) { }
}
Mubeen.delegate = Monitor()
Error Handling
MubeenSDKError is thrown for terminal failures. Every case carries a stable errorCode string suitable for logging and support tickets:
} catch let error as MubeenSDKError {
Log.error("Mubeen failed: \(error.errorCode)")
}
| Case | errorCode | When |
|---|---|---|
serverError | MUBEEN_E_SERVER | Server returned 400 / 401 / 403. |
killSwitchActive | MUBEEN_E_KILL_SWITCH | The SDK is disabled via remote config. |
configurationInvalid | — | configure called with an empty apiKey. |
| Not configured | MUBEEN_E_NOT_CONFIGURED | An API was used before configure() completed. |
Branch on the stable errorCode string, not on localized messages — the codes are guaranteed stable across SDK versions.
Related Documentation
- Server-Side Integration — Backend validation and API reference
- Android Integration — Native Android SDK integration guide
- Client-Side Integration — Web SDK integration guide
- Flutter Integration — Flutter plugin that wraps this SDK