Files
Christian Nennemann f57dda3f36 feat(sdk): add Swift and Kotlin mobile client foundations with push token proto
Swift SDK: Swift Package wrapping libquicproquo_ffi with QpqClient class
(connect, login, send, receive, disconnect) for iOS 15+ / macOS 13+.

Kotlin SDK: JNI bridge to libquicproquo_ffi with QpqClient class for
Android (aarch64, armv7) and JVM, Gradle build configuration.

Adds RegisterPushToken RPC (method ID 710) to device.proto for
APNs/FCM/WebPush device push token registration.
2026-03-04 20:58:23 +01:00
..

QuicProQuo Kotlin SDK

Kotlin/JVM wrapper over libquicproquo_ffi via JNI for Android and JVM platforms.

Prerequisites

  • Kotlin 1.9+ / JDK 17+
  • libquicproquo_ffi built for the target architecture
  • JNI bridge compiled (jni/dev_quicproquo_NativeBridge.c)

Building the Native Library

# Linux (JVM)
cargo build --release -p quicproquo-ffi

# Android (aarch64)
cargo build --release -p quicproquo-ffi --target aarch64-linux-android

# Android (armv7)
cargo build --release -p quicproquo-ffi --target armv7-linux-androideabi

Compiling the JNI Bridge

cd jni
gcc -shared -fPIC -o libquicproquo_jni.so \
    -I"$JAVA_HOME/include" -I"$JAVA_HOME/include/linux" \
    dev_quicproquo_NativeBridge.c \
    -L ../../../../target/release -lquicproquo_ffi

Installation

Gradle

dependencies {
    implementation(files("libs/quicproquo-0.1.0.jar"))
}

Or include as a local project module.

Usage

import dev.quicproquo.QpqClient

val client = QpqClient("127.0.0.1:5001", caCertPath = "ca.pem")

client.login("alice", "secret")
client.send("bob", "hello".toByteArray())

val messages = client.receive(timeoutMs = 5000)
messages.forEach { println("Received: $it") }

client.close()

API

Method Description
QpqClient(server, caCertPath, serverName) Connect to server
client.login(username, password) OPAQUE authentication
client.send(recipient, message) Send message by username
client.receive(timeoutMs) Receive pending messages
client.close() / client.disconnect() Disconnect
client.isConnected Connection status

Error Handling

try {
    client.login("alice", "wrong")
} catch (e: QpqAuthException) {
    println("Auth failed: ${e.message}")
} catch (e: QpqTimeoutException) {
    println("Timeout: ${e.message}")
} catch (e: QpqException) {
    println("Error: ${e.message}")
}

Structure

  • src/main/kotlin/dev/quicproquo/QpqClient.kt -- High-level client
  • src/main/kotlin/dev/quicproquo/NativeBridge.kt -- JNI declarations
  • src/main/kotlin/dev/quicproquo/QpqError.kt -- Exception types
  • jni/dev_quicproquo_NativeBridge.c -- JNI C bridge to FFI

Android Integration

  1. Add the native libraries to src/main/jniLibs/<abi>/:
    • arm64-v8a/libquicproquo_ffi.so
    • armeabi-v7a/libquicproquo_ffi.so
  2. Add the JNI bridge library alongside
  3. The NativeBridge class loads the library via System.loadLibrary

Cross-Compilation

# Install Android NDK targets
rustup target add aarch64-linux-android armv7-linux-androideabi

# Build with the NDK linker
CARGO_TARGET_AARCH64_LINUX_ANDROID_LINKER=aarch64-linux-android21-clang \
  cargo build --release -p quicproquo-ffi --target aarch64-linux-android