Skip to content

Latest commit

 

History

History
69 lines (51 loc) · 3.49 KB

File metadata and controls

69 lines (51 loc) · 3.49 KB

Kiche example app

A small Compose Multiplatform app (Android + Desktop/JVM + iOS) that demonstrates the ktor-client-kiche HTTP/3 client against public test servers. UX follows the Compose Multiplatform sample: a menu of buttons, each opening a feature screen.

Modules (the KMP plugin can't coexist with com.android.application in AGP 9, hence the split):

  • :example:shared — KMP library with the shared Compose UI/ViewModel, the desktop app entry, and the iOS ComposeApp framework + MainViewController.
  • :example:androidApp — pure Android application that depends on :example:shared.
  • example/iosApp — iOS app (not a Gradle module): an Xcode project generated by XcodeGen from project.yml, embedding the ComposeApp framework. See iosApp/README.md.

Screens

Screen What it does Endpoint
Connection & protocol QUIC + TLS 1.3 handshake; shows the negotiated protocol (expect HTTP/3.0) nghttp2.org/httpbin/get
Echo (POST body) POSTs a body, reads it back from the response JSON nghttp2.org/httpbin/post
Download bytes GETs a fixed number of bytes and times it nghttp2.org/httpbin/bytes/{n}
Streamed response Reads a chunked, newline-delimited streaming response nghttp2.org/httpbin/stream/{n}

A single pooled HttpClient is shared across screens (Http3DemoViewModel), so you can see Kiche's connection pooling: the first request handshakes, later ones reuse the connection.

Running

Desktop (works out of the box on macOS:kiche bundles a prebuilt libquiche_jni.dylib):

./gradlew :example:shared:run

Android requires the quiche JNI .so built for the device ABI via cargo-ndk (through :kiche). This path is not yet integration-tested. Once built:

./gradlew :example:androidApp:installDebug

iOS needs Xcode + XcodeGen (brew install xcodegen). The .xcodeproj is generated, not committed:

cd example/iosApp && xcodegen generate && open iosApp.xcodeproj

Pick a simulator and Run. The shared framework is built/embedded by an Xcode pre-build script; the first build also compiles quiche for iOS (slow once). Details in iosApp/README.md.

⚠️ TLS verification is disabled

The app sets verifyPeer = false in the Kiche engine on purpose, to avoid bundling a CA file. Kiche has no system trust store yet, so real verification needs an explicit caCertPath. This is fine for a demo against known servers — never ship verifyPeer = false in a real app. To verify properly, bundle a CA bundle (e.g. https://curl.se/ca/cacert.pem) and set caCertPath.

Notes / TODO

  • readUTF8Line deprecation (Streamed response screen). ByteReadChannel.readUTF8Line() is deprecated in ktor 3.4 (use readLine/readLineStrict). We keep bodyAsChannel() + readUTF8Line() because demonstrating the channel-based streaming-read pattern is the point of that screen. Tolerated for now; migrate when convenient.
  • Streaming is not yet truly incremental. The engine buffers the full response body before exposing it, so the streamed lines are counted from the assembled body. Real incremental delivery awaits engine-level response-body streaming.
  • iOS runs the same shared Compose UI via ComposeUIViewController. The whole Kotlin/native chain (Compose UI → ktor-client-kiche:kichelibquiche.a) links into the ComposeApp framework; build and run from Xcode — see iosApp/README.md.