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
}
}