KMPCharts/.paul/phases/v0.3.0-ios-build-plan.md
Trentin Davide d6f51cdef2 feat(ios): iOS build pipeline + XCFramework, fix K/Native source bugs
Modules: chart-realtime (commonMain, iosMain), root, .paul

- chart-realtime/build.gradle.kts: applyDefaultHierarchyTemplate() + XCFramework("ChartRealtime") over iosX64/iosArm64/iosSimulatorArm64, baseName CamelCase
- commonMain RealtimeChartState/CircularBuffer: switch to kotlin.concurrent.Volatile, add kotlin.jvm.JvmName import (OptionalExpectation)
- commonMain AxisRenderer: replace JVM-only String.format with multiplatform formatFixed/formatScientific/pow10 helpers
- iosMain Platform.ios.kt: NSDate() + timeIntervalSinceReferenceDate + 978_307_200s 1970-epoch offset (K/Native binding has no direct timeIntervalSince1970)
- gradle.properties: remove Linux JDK pin (rely on JAVA_HOME)
- .paul: phases plan, STATE+ROADMAP updates

Acceptance: A1 compile 3 iOS targets, A2 linkDebugFrameworkIosSimulatorArm64, A3 iosSimulatorArm64Test (33 tests, 0 failures), A4 assembleChartRealtimeXCFramework (ios-arm64 + ios-arm64_x86_64-simulator slices), A5 Android assembleRelease/publishToMavenLocal --dry-run.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-21 12:45:21 +02:00

109 lines
4.9 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# v0.3.0 — iOS Build & Test Pipeline Plan
## Goal
Wire `chart-realtime` for full iOS pipeline: compile all 3 iOS targets, link debug framework on `iosSimulatorArm64`, run `commonTest` on iOS sim, produce release `XCFramework`. Keep Android green. No new features, no demo app, no SPM/CocoaPods/CI.
Acceptance:
- A1: `./gradlew :chart-realtime:compileKotlinIosX64 compileKotlinIosArm64 compileKotlinIosSimulatorArm64` green
- A2: `./gradlew :chart-realtime:linkDebugFrameworkIosSimulatorArm64` green
- A3: `./gradlew :chart-realtime:iosSimulatorArm64Test` green, executes existing common tests
- A4: `./gradlew :chart-realtime:assembleXCFramework` produces `chart-realtime/build/XCFrameworks/release/chart-realtime.xcframework`
- A5: `./gradlew :chart-realtime:assemble` green (Android non-regression)
## Locked decisions
- T0: remove `org.gradle.java.home` pin (rely on JAVA_HOME)
- XCFramework baseName: `ChartRealtime` (CamelCase iOS convention)
- Include `iosX64` target in XCFramework
- Local Mac dev only, no CI
---
## Tasks
### T0 — Mac JDK / gradle.properties sanity
- Goal: Unblock local Mac build. Current `gradle.properties` pins Linux JDK path. Pre-req for A1A5.
- Files: `gradle.properties`
- Agent: `gradle-expert`
- Action: remove line `org.gradle.java.home=/home/dtrentin/.local/share/JetBrains/Toolbox/apps/android-studio/jbr`. Keep other lines unchanged.
- Deps: none
- Verify: `./gradlew :chart-realtime:help`
### T1+T2+T4 — Batched build.gradle.kts edit
- Goal: iOS hierarchy explicit + XCFramework task.
- Files: `chart-realtime/build.gradle.kts`
- Agent: `gradle-expert` (single edit, single agent)
- Actions:
- Apply default hierarchy template explicitly (`applyDefaultHierarchyTemplate()`)
- Configure each iOS target with `binaries.framework { baseName = "ChartRealtime"; xcf.add(this) }` using `XCFramework("ChartRealtime")` helper from `org.jetbrains.kotlin.gradle.plugin.mpp.apple.XCFramework`
- Keep `compose.material3` in `commonMain` (CMP 1.8.0 supports iOS native)
- Do not break Android target, publishing, or existing source-set deps
- Deps: T0
- Verify:
- `./gradlew :chart-realtime:compileKotlinIosX64`
- `./gradlew :chart-realtime:compileKotlinIosArm64`
- `./gradlew :chart-realtime:compileKotlinIosSimulatorArm64`
- `./gradlew :chart-realtime:linkDebugFrameworkIosSimulatorArm64`
- `./gradlew :chart-realtime:assembleXCFramework`
### T3 — iosTest wiring
- Goal: `iosTest` source set runs existing `commonTest` files on iOS sim.
- Files: `chart-realtime/build.gradle.kts` (only if hierarchy template doesn't auto-wire)
- Agent: `unit-test-writer`
- Inputs: existing `commonTest.dependencies { implementation(libs.kotlin.test) }`. Default hierarchy template wires `iosTest → commonTest` automatically. Verify; add explicit block only if test discovery fails.
- Deps: T1+T2+T4
- Verify: `./gradlew :chart-realtime:iosSimulatorArm64Test`
### T5 — Android non-regression guard
- Goal: Confirm Android target/build/publish untouched.
- Agent: `android-build-resolver`
- Deps: T1+T2+T4
- Verify: `./gradlew :chart-realtime:assembleRelease publishToMavenLocal --dry-run`
### T6 — Smoke acceptance run
- Goal: Sequential run of all 5 acceptance commands.
- Agent: `general-purpose`
- Deps: T3, T5
- Verify: all 5 commands green
---
## Parallelism
| Group | Tasks |
|-------|-------|
| P0 | T0 |
| P1 | T1+T2+T4 (one batched agent call) |
| P2 | T3, T5 (parallel) |
| P3 | T6 |
| P4 | Unify |
---
## Risks
- R1: gradle.properties Linux JDK path — fixed in T0
- R2: `compose.material3` iOS native — supported in 1.8.0; fallback = isolate to non-iOS if compile fails
- R3: Hierarchy template silent inactivity — `applyDefaultHierarchyTemplate()` made explicit
- R4: `commonTest` not seen by `iosTest` — same hierarchy fix
- R5: XCFramework name collision — single `XCFramework("ChartRealtime")` registration
- R6: Compose link errors on iOS — defer to v0.4.0 if hit
- R7: Android regression — T5 final gate, revert if needed
- R8: Sim runtime requirement — confirmed installed (iPhone 17 family available)
## New Deps
None. KGP + CMP 1.8.0 + Kotlin 2.1.0 cover everything.
## Verification Commands
```bash
./gradlew :chart-realtime:help # T0
./gradlew :chart-realtime:compileKotlinIosX64 # A1
./gradlew :chart-realtime:compileKotlinIosArm64 # A1
./gradlew :chart-realtime:compileKotlinIosSimulatorArm64 # A1
./gradlew :chart-realtime:linkDebugFrameworkIosSimulatorArm64 # A2
./gradlew :chart-realtime:iosSimulatorArm64Test # A3
./gradlew :chart-realtime:assembleXCFramework # A4
ls chart-realtime/build/XCFrameworks/release/ChartRealtime.xcframework # A4
./gradlew :chart-realtime:assembleRelease # A5
./gradlew :chart-realtime:publishToMavenLocal --dry-run # T5
```