KMPCharts/samples/ios/ChartRealtimeDemo/README.md
Trentin Davide 07197ed8df
Some checks are pending
CI / build (push) Waiting to run
chore(portfolio): v1.0.0 prep — docs, CI, demos
Autonomous portfolio prep batch. All gates green: 207 tests pass on
iosSimulatorArm64Test, assembleRelease green, apiCheck green, app builds.

Docs:
- CHANGELOG.md (Keep-a-Changelog, retroactive v0.1-v0.5)
- CONTRIBUTING.md (build + style + PR workflow + perf rules)
- chart-realtime/README.md rewrite for v0.5.0 API surface
- docs/PERFORMANCE.md (LoD perf table, alloc budget, memory budget,
  stability report, threading model)

CI (.github/):
- workflows/ci.yml — macos-latest, JDK 21, konan cache, full gate
- workflows/release.yml — tag-triggered, GitHub release with XCFramework
  + AAR; Maven Central as commented TODO (needs OSSRH + GPG secrets)
- dependabot.yml — weekly gradle + actions updates
- pull_request_template.md + 2 issue templates (bug, feature)

Android demo polish:
- DemoScreen + ControlPanel (Material3 surface)
- Sample rate slider (10..200Hz), 1-6 signal count, per-signal waveform
  picker (sine/square/triangle/noise), window seconds, LoD picker, Y
  label mode, Y formatter, interaction toggle, theme switch, status chips
- Single producer coroutine (cleaner crosshair readout, easier rate
  accounting)
- SignalGenerator + WaveformType + DemoConfig + PushCounter

iOS demo scaffold (samples/ios/ChartRealtimeDemo/):
- SPM Package.swift with local binaryTarget pointing to
  chart-realtime/build/XCFrameworks/debug/ChartRealtime.xcframework
- DemoApp.swift + DemoView.swift (smoke test confirming Kotlin types
  accessible from Swift)
- README documents the ComposeUIViewController shim needed in
  chart-realtime/src/iosMain/ for full SwiftUI hosting (deferred to
  v1.0.0 T1)
- xcodebuild against iOS Simulator builds green

Debt:
- gradle.properties: removed kotlin.internal.klibs.non-packed=false
  (Compose-MP 1.11.0 final no longer needs the bypass; apiCheck +
  native compile + 207 tests still green)
- 8 remaining deprecation warnings tied to com.android.library + KMP
  plugin combo; clearing them requires migration to
  com.android.kotlin.multiplatform.library 9.2.0 which forces ABI
  baseline regen + Maven publish restructure + XCFramework hierarchy
  expansion. Deferred as dedicated ticket.

Skipped (need user):
- CODE_OF_CONDUCT.md (content classifier blocks Contributor Covenant
  verbatim)
- Maven Central T1 (Sonatype + GPG)
- Benchmark vs competitors T4 (methodology + Maven coords)
- Logo/banner/GIF T7 (design assets)
- Tag + GitHub release T10 (rename pending)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-22 10:54:26 +02:00

118 lines
3.9 KiB
Markdown

# ChartRealtime iOS Demo
SwiftUI app consuming `ChartRealtime.xcframework` via Swift Package Manager.
## Build
Prerequisites:
- Xcode 15+
- macOS on Apple Silicon (Intel Mac simulators are NOT supported since v0.5.0)
- Local `ChartRealtime.xcframework` built via Gradle
From the repo root:
```bash
./gradlew :chart-realtime:assembleChartRealtimeDebugXCFramework
```
This produces:
```
chart-realtime/build/XCFrameworks/debug/ChartRealtime.xcframework
```
The `Package.swift` references it via a local `binaryTarget`:
```swift
.binaryTarget(
name: "ChartRealtime",
path: "../../../chart-realtime/build/XCFrameworks/debug/ChartRealtime.xcframework"
)
```
Then resolve + build the SPM package:
```bash
cd samples/ios/ChartRealtimeDemo
swift package resolve
swift build
```
To run the app, open the package in Xcode (`File > Open... > Package.swift`)
or wrap it in a thin app target. A standalone `xcodeproj` is intentionally NOT
shipped in this scaffold.
## Current limitation
`chart-realtime` exposes the `@Composable fun RealtimeChart` composable, but it
does NOT yet export a `ComposeUIViewController` factory wrapping it into a
plain `UIViewController` suitable for SwiftUI hosting.
Until that bridge ships (planned for `v1.0.0` T1), this demo:
- Verifies the XCFramework is consumable from Swift via SPM `binaryTarget`
- Instantiates the full Kotlin-side public API (`RealtimeChartState`,
`ChartConfig`, `DataConfig`, `AxisConfig`, `RenderConfig`,
`MinMaxLttbLodStrategy`, `TimeAxisFormatter`, `DecimalAxisFormatter`,
`YRange.Auto`, `T0.FirstSample`, `FrameRate.Display`,
`LineSignalRenderer`, `SignalConfig`, `ChartTheme`) from SwiftUI
- Registers a signal via `state.addSignal(name:signalConfig:)`
- Does NOT render the actual chart
## Enabling the full demo (post-v1.0.0 T1)
In `chart-realtime/src/iosMain/`:
```kotlin
import androidx.compose.ui.window.ComposeUIViewController
import platform.UIKit.UIViewController
public fun RealtimeChartViewController(
state: RealtimeChartState,
xWindowSeconds: Float = state.config.data.xWindowSeconds,
): UIViewController = ComposeUIViewController {
RealtimeChart(state = state, xWindowSeconds = xWindowSeconds)
}
```
Then in SwiftUI:
```swift
import SwiftUI
import ChartRealtime
import UIKit
struct ChartHost: UIViewControllerRepresentable {
let state: RealtimeChartState
func makeUIViewController(context: Context) -> UIViewController {
// Kotlin top-level functions are exposed under the Kt-suffixed class
// in the auto-generated ObjC header; exact symbol depends on file name.
return RealtimeChartViewControllerKt.RealtimeChartViewController(
state: state,
xWindowSeconds: 10.0
)
}
func updateUIViewController(_ uiViewController: UIViewController, context: Context) {}
}
```
## ObjC bridge gotchas observed while authoring this demo
- All Kotlin data-class constructors lose default arguments when crossing the
ObjC bridge — callers must pass every constructor argument explicitly.
- Sealed-class objects (`YRange.Auto`, `T0.FirstSample`, `FrameRate.Display`)
are exposed as classes with no-arg `init()`. Use `YRange.Auto()`, etc.
- Compose `Color` is bridged as `uint64_t` (Kotlin `ULong`) — pass raw ARGB
packed values: `0xFF00FF88` for opaque mint green.
- `LineSignalRenderer` is a Kotlin `object` (singleton) — both `LineSignalRenderer()`
and `LineSignalRenderer.shared` work in Swift.
- `dataVersion` is currently not exposed as a Swift-visible property of
`RealtimeChartState` (it is a Compose `MutableState<Int>` not flattened by
Kotlin/Native ObjC export). A `var dataVersionInt: Int` getter would help.
## Files
- `Package.swift` — SPM manifest, links `ChartRealtime.xcframework` via local `binaryTarget`
- `Sources/ChartRealtimeDemo/DemoApp.swift` — SwiftUI `@main` entry point
- `Sources/ChartRealtimeDemo/DemoView.swift` — placeholder view + Kotlin smoke test