Skip to content

feat(codegen): native Swift generator + iOS example over the C ABI#59

Draft
Ivansete-status wants to merge 3 commits into
ffi-native-typed-returnsfrom
ios-example
Draft

feat(codegen): native Swift generator + iOS example over the C ABI#59
Ivansete-status wants to merge 3 commits into
ffi-native-typed-returnsfrom
ios-example

Conversation

@Ivansete-status

Copy link
Copy Markdown
Collaborator

Adds an iOS example consuming the timer library's native (zero-serialization)
C ABI from Swift. Based on the native-FFI stack (#58) so it can use typed struct
returns.

What

  • examples/timer/ios/ — a SwiftPM package with an idiomatic TimerNode Swift
    wrapper over the native ABI. Struct returns (EchoResponse) come back as typed
    Swift values, read out of the C-POD inside the result callback.
  • build-xcframework.sh cross-compiles the Nim library to a static
    MyTimer.xcframework with ios-arm64 (device), ios-arm64-simulator, and
    macos-arm64 slices. The xcframework is assembled by hand (no
    xcodebuild -create-xcframework), so it builds headless / in CI.

Validation

  • Cross-compiles cleanly for device + simulator (correct arm64 slices, native +
    CBOR symbols present).
  • The macos-arm64 slice makes the wrapper host-testable: swift test passes
    (create / version / typed echo / a 200-iteration loop).

Separate PR, as requested. Sibling to the Android example PR; both target the
stack tip and retarget to master once it lands.

🤖 Generated with Claude Code

A SwiftPM package wrapping the timer library's native ABI behind an idiomatic
`TimerNode` Swift class. `build-xcframework.sh` cross-compiles the Nim library
to a static MyTimer.xcframework with three slices — ios-arm64 (device),
ios-arm64-simulator, and macos-arm64 — assembling the .xcframework by hand so it
works without a functioning Simulator toolchain (CI-friendly).

The wrapper bridges the async FFI-thread callback to a synchronous Swift API
with a semaphore and reads the typed EchoResponse struct out of the callback.
The macos-arm64 slice makes the wrapper testable on the host: `swift test`
passes against it. Device/simulator slices are the real iOS deployment artifacts.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@Ivansete-status
Ivansete-status force-pushed the ffi-native-typed-returns branch from 1060340 to c000a84 Compare May 31, 2026 16:38
@Ivansete-status
Ivansete-status marked this pull request as draft June 1, 2026 07:34
Ivansete-status and others added 2 commits June 13, 2026 16:39
Adds ffi/codegen/swift.nim, wired into the targetLang dispatch and exposed
as the `genbindings_swift` nimble task. It emits an idiomatic Swift wrapper
over the native (zero-serialization) C ABI from c.nim — importing the C
structs through the CMyTimer clang module and never touching CBOR.

The one piece of real logic is callback-shape selection: ack / string /
struct decoding is chosen per proc from FFIProcMeta.kind + returnTypeName,
and struct returns are copied out inside the callback to honour the
deep-free-after-callback ownership rule. A single struct param's fields are
flattened into the Swift method signature; ctors keep argument labels.

Procs needing seq/Option or multi-struct param marshaling are skipped with a
logged notice rather than emitting broken Swift, so the wrapper always
compiles. That marshaling, events, and async mapping are the next increments.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Regenerates Sources/MyTimer/MyTimer.swift via `nimble genbindings_swift`
(replacing the hand-written wrapper) and points the tests at the derived
MyTimerNode class. Proves the generator reproduces the validated
create/version/echo path: build-xcframework.sh + `swift test` pass 2/2 on
the macOS slice.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@Ivansete-status Ivansete-status changed the title docs(examples): iOS (Swift) example over the native C ABI feat(codegen): native Swift generator + iOS example over the C ABI Jun 13, 2026
@Ivansete-status

Copy link
Copy Markdown
Collaborator Author

Expanded scope: this PR now also adds the Swift generator that produces the wrapper, not just the hand-written example.

  • ffi/codegen/swift.nim — emits an idiomatic Swift wrapper over the native C ABI (imports the CMyTimer clang module, never touches CBOR). Wired into the targetLang dispatch + a genbindings_swift nimble task.
  • Sources/MyTimer/MyTimer.swift is now generated (was hand-written); tests retargeted to the derived MyTimerNode.
  • Callback-shape selection (ack / string / struct) is chosen per proc from FFIProcMeta; struct returns are copied out inside the callback (deep-free-after-callback rule).
  • Procs needing seq/Option or multi-struct param marshaling (complex, schedule) are skipped with a logged notice so the wrapper always compiles — that marshaling, events, and async are the next increments.

Validated: build-xcframework.sh + swift test pass 2/2 on the macOS slice.

🤖 Generated with Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant