Skip to content

Mobile ID SDK basic usage examples

Kotlin (Android) example

Basic setup and initialization

import de.baltech.mobileid.*
import androidx.lifecycle.lifecycleScope
import kotlinx.coroutines.launch

class MainActivity : ComponentActivity() {
    private lateinit var sdk: MobileIdSdk

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        // Initialize SDK
        sdk = MobileIdSdk()

        // Enable debug logging for development
        sdk.debugMode = true

        // Set up callbacks
        setupCallbacks()

        // Create and activate credential
        activateCredential()
    }

    private fun setupCallbacks() {
        // Monitor availability changes
        sdk.onAvailabilityChange = { availability ->
            handleAvailabilityChange(availability)
        }

        // Monitor reader updates
        sdk.onReadersUpdate = {
            val readers = sdk.readers
            println("Readers available: ${readers.size}")
        }
    }

    private fun activateCredential() {
        lifecycleScope.launch {
            val projectKey = "00112233445566778899AABBCCDDEEFF".hexToByteArray()
            val credential = Credential.create(
                projectKey = projectKey,
                credentialId = "user_001"
            )
            sdk.credentials = listOf(credential)
        }
    }

    private fun handleAvailabilityChange(availability: Availability) {
        when (availability) {
            AvailabilityStates.OK -> {
                // Ready to use
                println("SDK ready")
            }
            AvailabilityStates.DISABLED -> {
                // Show "Please enable Bluetooth"
                showBluetoothDisabledMessage()
            }
            AvailabilityStates.PERMISSIONS_DENIED,
            AvailabilityStates.PERMISSIONS_REQUIRED -> {
                // SDK will automatically request permissions
                // Or manually request if preferred
                lifecycleScope.launch {
                    sdk.requestPermissions()
                }
            }
            AvailabilityStates.PERMISSIONS_PERMANENTLY_DENIED -> {
                // Must use settings
                showPermissionPermanentlyDeniedDialog()
            }
        }
    }

    private fun showPermissionPermanentlyDeniedDialog() {
        // Show dialog explaining why permissions needed
        AlertDialog.Builder(this)
            .setTitle("Bluetooth Permissions Required")
            .setMessage("Please enable Bluetooth permissions in Settings to use Mobile ID")
            .setPositiveButton("Open Settings") { _, _ ->
                lifecycleScope.launch {
                    sdk.openPermissionSettings()
                }
            }
            .show()
    }
}

// Utility extension
fun String.hexToByteArray(): ByteArray {
    return chunked(2).map { it.toInt(16).toByte() }.toByteArray()
}

Using Compose UI with log viewer

@Composable
fun App() {
    val sdk = remember { MobileIdSdk() }
    var currentScreen by remember { mutableStateOf(Screen.HOME) }

    when (currentScreen) {
        Screen.HOME -> {
            HomeScreen(
                sdk = sdk,
                onViewLogs = { currentScreen = Screen.LOGS }
            )
        }
        Screen.LOGS -> {
            LogViewerScreen(sdk = sdk)
        }
    }
}

@Composable
fun LogViewerScreen(sdk: MobileIdSdk) {
    Scaffold(
        topBar = {
            TopAppBar(title = { Text("SDK Logs") })
        }
    ) { padding ->
        Box(modifier = Modifier.padding(padding)) {
            sdk.createLogView()  // Optional: Shows SDK logs
        }
    }
}

Implementing support integration

@Composable
fun SupportButton(sdk: MobileIdSdk) {
    val scope = rememberCoroutineScope()

    Button(
        onClick = {
            scope.launch {
                try {
                    sdk.sendLogs(
                        subject = "MyApp Support Request",
                        message = "User encountered issue with access control"
                    )
                } catch (e: IllegalStateException) {
                    // No logs available
                }
            }
        }
    ) {
        Text("Contact Support")
    }
}

Triggering readers

@Composable
fun ReaderList(sdk: MobileIdSdk) {
    var readers by remember { mutableStateOf<List<Reader>>(emptyList()) }

    LaunchedEffect(Unit) {
        sdk.onReadersUpdate = {
            readers = sdk.readers
        }
    }

    LazyColumn {
        items(readers) { reader ->
            Card(
                modifier = Modifier
                    .fillMaxWidth()
                    .clickable { reader.trigger() }
                    .padding(8.dp)
            ) {
                Text(
                    text = reader.displayName,
                    modifier = Modifier.padding(16.dp)
                )
            }
        }
    }
}

Swift (iOS) example

Basic setup and initialization

import SwiftUI
import MobileIDSdk

class SDKManager: ObservableObject {
    let sdk: MobileIdSdk
    @Published var availability: String = AvailabilityStates.shared.UNDEFINED
    @Published var readers: [Reader] = []

    init() {
        sdk = MobileIdSdk()

        // Enable debug logging
        sdk.debugMode = true

        // Set up callbacks
        setupCallbacks()
    }

    private func setupCallbacks() {
        // Monitor availability
        sdk.onAvailabilityChange = { [weak self] newAvailability in
            DispatchQueue.main.async {
                self?.availability = newAvailability
                self?.handleAvailabilityChange(newAvailability)
            }
        }

        // Monitor readers
        sdk.onReadersUpdate = { [weak self] in
            DispatchQueue.main.async {
                self?.readers = self?.sdk.readers ?? []
            }
        }
    }

    func activateCredential() {
        let projectKeyHex = "00112233445566778899AABBCCDDEEFF"
        guard let projectKey = try? projectKeyHex.hexToByteArray() else {
            return
        }

        let credential = Credential.Companion().create(
            projectKey: projectKey.toKotlinByteArray(),
            credentialId: "user_001",
            onTrigger: nil
        )

        sdk.credentials = [credential]
    }

    private func handleAvailabilityChange(_ availability: String) {
        let states = AvailabilityStates.shared

        switch availability {
        case states.OK:
            print("SDK ready")

        case states.DISABLED:
            showAlert("Please enable Bluetooth")

        case states.PERMISSIONS_DENIED, states.PERMISSIONS_REQUIRED:
            // SDK automatically requests - or manually request
            Task {
                try? await sdk.requestPermissions()
            }

        case states.PERMISSIONS_PERMANENTLY_DENIED:
            showPermissionSettings()

        default:
            print("Availability: \(availability)")
        }
    }

    private func showPermissionSettings() {
        // Show alert with option to open settings
        Task {
            try? await sdk.openPermissionSettings()
        }
    }

    func sendSupportEmail() {
        Task {
            try? await sdk.sendLogs(
                subject: "MyApp Support Request",
                message: "User needs assistance"
            )
        }
    }
}

// Utility extension for hex conversion
extension String {
    func hexToByteArray() throws -> [UInt8] {
        var bytes = [UInt8]()
        var index = startIndex
        while index < endIndex {
            let nextIndex = self.index(index, offsetBy: 2)
            let byteString = self[index..<nextIndex]
            guard let byte = UInt8(byteString, radix: 16) else {
                throw NSError(domain: "Invalid hex", code: -1)
            }
            bytes.append(byte)
            index = nextIndex
        }
        return bytes
    }
}

extension Array where Element == UInt8 {
    func toKotlinByteArray() -> KotlinByteArray {
        let data = Data(self)
        return KotlinByteArray(size: Int32(data.count)) { index in
            return Int8(bitPattern: data[Int(truncating: index)])
        }
    }
}

SwiftUI view integration

struct ContentView: View {
    @StateObject private var sdkManager = SDKManager()

    var body: some View {
        NavigationView {
            VStack {
                // Availability Status
                AvailabilityStatusView(availability: sdkManager.availability)

                // Reader List
                List(sdkManager.readers, id: \.displayName) { reader in
                    Button(action: {
                        reader.trigger()
                    }) {
                        Text(reader.displayName)
                    }
                }

                // Support Button
                Button("Contact Support") {
                    sdkManager.sendSupportEmail()
                }
                .padding()
            }
            .navigationTitle("Mobile ID")
            .onAppear {
                sdkManager.activateCredential()
            }
        }
    }
}

struct AvailabilityStatusView: View {
    let availability: String

    var body: some View {
        HStack {
            Text("Status:")
            Text(availability)
                .fontWeight(.bold)
                .foregroundColor(statusColor)
        }
        .padding()
    }

    var statusColor: Color {
        let states = AvailabilityStates.shared
        switch availability {
        case states.OK:
            return .green
        case states.DISABLED, states.UNAUTHORIZED:
            return .red
        case states.PERMISSIONS_DENIED, states.PERMISSIONS_REQUIRED:
            return .orange
        default:
            return .gray
        }
    }
}

Using log viewer (optional)

struct LogViewerView: View {
    let sdk: MobileIdSdk

    var body: some View {
        NavigationView {
            LogViewControllerWrapper(
                viewController: sdk.createLogViewController()
            )
            .navigationTitle("SDK Logs")
        }
    }
}

struct LogViewControllerWrapper: UIViewControllerRepresentable {
    let viewController: UIViewController

    func makeUIViewController(context: Context) -> UIViewController {
        return viewController
    }

    func updateUIViewController(_ uiViewController: UIViewController, context: Context) {
        // No updates needed
    }
}
Title