Skip to content

feat(shared-core): wrap the framework in a Swift target - #1297

Merged
bmc08gt merged 2 commits into
code/cashfrom
feat/shared-core-swift-bridge
Aug 21, 2026
Merged

feat(shared-core): wrap the framework in a Swift target#1297
bmc08gt merged 2 commits into
code/cashfrom
feat/shared-core-swift-bridge

Conversation

@bmc08gt

Copy link
Copy Markdown
Collaborator

Follows #1294 / #1295. The published package now exposes Swift, not Kotlin/Native.

The problem

0.1.0 shipped the raw XCFramework as its only product, so an iOS caller had to do
the bridging itself:

letarray=KotlinByteArray(size:Int32(payload.count))for(i, b)in payload.enumerated(){ array.set(index:Int32(i), value:Int8(bitPattern: b))}letsvg=KikCodeSvg.shared.render(payload: array, dimension:1024, foreground:"#FFFFFF", background:nil, includeBadge:true)

ByteArray has no Data bridge, Kotlin objects arrive as .shared, and default
arguments aren't exported at all — every call site has to pass every parameter.

The change

  • A SharedCoreKit Swift target sits over the binary framework and is the package's
    only product; the framework is now an implementation detail of it. Callers write
    KikCode.svg(payload: data) with Data and real defaults.
  • The Swift sources live in kmp/shared-core/spm/ — next to the Kotlin they wrap, so
    glue and Kotlin move in one commit and the Swift Package repo stays a publish target
    rather than a place to edit. The job copies Package.swift, Sources/, and Tests/
    across before Gradle runs; KMMBridge is switched to useCustomPackageFile, which
    rewrites only the variables block inside our file.
  • The job builds the staged package against the framework it just uploaded, before it
    moves the tag — the last point at which a mismatch between the Swift and the Kotlin
    is cheap to fix.

The linkage bug it turned up

Building the package standalone failed to link: _ed25519_sign and _ed25519_verify
were undefined in the shipped framework. binaries.linkerOpts only affects the binaries
:libs:encryption:ed25519 itself produces, so the C objects never reached a downstream
framework. Nothing had failed before because the iOS app compiles the same C reference
implementation and satisfied the symbols by accident. The cinterop now embeds
libored25519.a into the klib, so anything built from it carries them.

`binaries.linkerOpts` only reaches the binaries this module itself produces, so
the ed25519 objects never travelled into a downstream framework -- the shared-core
XCFramework exported `_ed25519_sign`/`_ed25519_verify` as undefined and left every
consumer to supply them. The iOS app happens to compile the same C reference
implementation, which is why nothing had failed yet; a standalone SPM consumer
fails to link.
`-staticLibrary`/`-libraryPath` on the cinterop puts the archive in the klib, so
anything built from it carries the symbols.
The Kotlin/Native ObjC surface is not something an app should have to hold: byte
payloads arrive as `KotlinByteArray`, objects come through `.shared`, and default
arguments don't survive the export at all. Adding a `SharedCoreKit` Swift target
over the binary framework moves that translation into the package -- iOS calls
`KikCode.svg(payload:)` with `Data` and named defaults, and the framework itself
is no longer a product.
The Swift sources live here rather than in the Swift Package repo so the glue and
the Kotlin it wraps move in one commit; the publish job copies them across, which
also means `Package.swift` is ours now (KMMBridge rewrites only its variables
block). The job builds the staged package against the framework it just uploaded
before moving the tag, so a mismatch between the two can't reach a consumer.
@github-actionsgithub-actionsBot added type: feature New functionality area: crypto Solana, keys, encryption, signing and removed type: feature New functionality labels Aug 21, 2026
@bmc08gt
bmc08gt merged commit de08a67 into code/cashAug 21, 2026
3 of 4 checks passed
bmc08gt added a commit that referenced this pull request Aug 21, 2026
…esign
* origin/code/cash:
fix(core): add \ to escape ' in What's (#1298)
feat(shared-core): wrap the framework in a Swift target (#1297)
chore: update display name entry title/hint (#1296)
ci(shared-core): write a placeholder local.properties before publishing (#1295)
build(shared-core): publish the XCFramework to flipcash-shared-core-spm (#1294)
refactor(build-logic): extract the KMP test-fixture generator into a convention plugin (#1293)
build(base58): declare the base58 lint tasks' dependency on generated fixtures (#1292)
test(base58): run the vector gate on Kotlin/Native, not just the JVM (#1289)
build(codes): declare the kikcode lint tasks' dependency on generated fixtures (#1288)
# Conflicts:
#	apps/flipcash/core/src/main/res/values/strings.xml
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: cryptoSolana, keys, encryption, signing

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@bmc08gt