Skip to content

feat(swift): add Swift SDK with TCP and TLS transport - #4112

Closed
RustToMetal wants to merge 2 commits into
apache:masterfrom
RustToMetal:feat/swift-sdk-4001
Closed

RustToMetal wants to merge 2 commits into
apache:masterfrom
RustToMetal:feat/swift-sdk-4001

Conversation

@RustToMetal

Copy link
Copy Markdown

Adds a native Swift client for the VSR wire protocol so Swift applications on Apple platforms and Linux can talk to Iggy without a bridge. The SDK matches the Rust client's surface: every stream, topic, partition, message, consumer-group, offset, user, personal-access-token, and system command, a producer with direct and background batching modes, and a consumer that is an AsyncSequence with the same auto-commit modes. Reconnection restores the session and replays only requests that provably never reached the log; leader redirection and roster failover follow the cluster like the Rust TcpClient.

The wire layer is proven byte-identical to the Rust crates through golden vectors emitted by a small Rust generator, and the client's reconnection, replay, eviction, and timeout paths run against an in-process VSR server over real sockets. The end-to-end suite runs against iggy-server with and without TLS, the examples run through the shared README runner, and the BDD scenarios run through a Swift Gherkin interpreter in Docker.

SwiftPM cannot fetch a package from a repository subdirectory, so the release flow tags foreign/swift/v<version> here and the README points at the package mirror for consumers.

Which issue does this PR address?

Closes #4001

Rationale

Iggy has no first-class client for Swift, so apps on iOS, macOS, and server-side Swift cannot use it without wrapping another SDK. #4001 asks for a native, idiomatic Swift SDK; this is Phase 1 of that issue (TCP and TLS over the VSR protocol), with QUIC, HTTP, and WebSocket left for later phases.

What changed?

Before, a Swift application had no way to speak the VSR wire protocol: no frame encoder, no session handling, and no typed models for the server's commands and replies.

This adds foreign/swift, a SwiftPM package built on SwiftNIO and NIOSSL in Swift 6 strict-concurrency mode. It implements the consensus framing, sessions, result-framed replies, batch layout, and XXH3/XXH32 natively, exposes IggyClient with the full command set plus IggyProducer and IggyConsumer, and ships with examples in examples/swift, a BDD runner in bdd/swift, CI lanes (lint, test, build, e2e plain and TLS, BDD, examples), and tag-only release wiring mirroring the Go SDK.

Local Execution

  • Passed
  • Pre-commit hooks not ran (prek is not installed here; shellcheck, markdownlint, swift format lint --strict, swift build -Xswiftc -warnings-as-errors, license-header, trailing-whitespace, and trailing-newline checks were run by hand and are clean)

Everything below was run locally against a fresh iggy-server built from this branch:

Check Result
Unit and fake-server suite (189 tests), 10 consecutive runs 10/10 green
End-to-end suite (35 tests) against a plain server, 8 runs 8/8 green
End-to-end suite against a TLS server (core/certs), 8 runs 8/8 green
scripts/run-examples-from-readme.sh --language swift (plain and TLS) pass
BDD scenarios natively (macOS, Swift 6.2) and in the Linux Docker image (Swift 6.1) 9/9 both
Live server kill and restart while producing and consuming reconnected and signed in on its own, 200/200 messages consumed once with contiguous offsets

The Linux container run caught one real bug during verification (TCP_NODELAY was being set at the socket level, which Linux refuses without CAP_NET_ADMIN); the fix is included.

Not verifiable on this machine: the GitHub workflows have not run on GitHub yet, and the compose-driven BDD flow needs a Linux server binary, so the container was run directly against a host server instead.

AI Usage

  1. Which tools? Claude Code (Claude).
  2. Scope of usage? The implementation, tests, examples, BDD runner, CI wiring, and documentation were drafted with it, working from the Rust SDK and core/binary_protocol as the reference, and reviewed and directed by me.
  3. How did you verify the generated code works correctly? The wire encoding is checked byte-for-byte against golden vectors generated by the Rust crates (240 error codes, 318 hash vectors, 117 request and response vectors). The client transport is tested against a scripted in-process VSR server over real sockets, the producer and consumer against an in-memory backend, and everything end to end against a real iggy-server with and without TLS, plus the examples runner, the BDD suite on macOS and Linux, and a live server-restart probe (table above). All suites were run repeatedly to shake out flakiness.
  4. Can you explain every line of the code if asked? Yes.

Adds a native Swift client for the VSR wire protocol so Swift applications
on Apple platforms and Linux can talk to Iggy without a bridge. The SDK
matches the Rust client's surface: every stream, topic, partition, message,
consumer-group, offset, user, personal-access-token, and system command,
a producer with direct and background batching modes, and a consumer that
is an AsyncSequence with the same auto-commit modes. Reconnection restores
the session and replays only requests that provably never reached the log;
leader redirection and roster failover follow the cluster like the Rust
TcpClient.

The wire layer is proven byte-identical to the Rust crates through golden
vectors emitted by a small Rust generator, and the client's reconnection,
replay, eviction, and timeout paths run against an in-process VSR server
over real sockets. The end-to-end suite runs against iggy-server with and
without TLS, the examples run through the shared README runner, and the
BDD scenarios run through a Swift Gherkin interpreter in Docker.

SwiftPM cannot fetch a package from a repository subdirectory, so the
release flow tags foreign/swift/v<version> here and the README points at
the package mirror for consumers.

Closes apache#4001
@github-actions

github-actions Bot commented Sep 9, 2026

Copy link
Copy Markdown

Thanks for the PR. It is labeled S-waiting-on-review and queued for review.

Slash commands (own line, regular comment) move it around the queue:

  • /ready - back to S-waiting-on-review after addressing feedback
  • /author - flip to S-waiting-on-author while you finish changes
  • /request-review @user-or-team - request a reviewer
  • /pin - exempt the PR from the stale bot, /unpin to undo

See CONTRIBUTING.md for details.

@github-actions github-actions Bot added the S-waiting-on-review PR is waiting on a reviewer label Sep 9, 2026
@slbotbm

slbotbm commented Sep 11, 2026

Copy link
Copy Markdown
Contributor

@RustToMetal it would be better to split this into multiple PRs since reviewing 23k loc, even wih agents, is not possible. The first PR should wire in the CI with a little swift code to check that the wiring works, and then you can work from there.

@hubcio

hubcio commented Sep 11, 2026

Copy link
Copy Markdown
Contributor

@slbotbm agreed. @RustToMetal max 3k LoC per PR, please. (5k is hard limit 😄)

@codecov

codecov Bot commented Sep 12, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 86.03%. Comparing base (d693eb9) to head (80fcc39).
⚠️ Report is 17 commits behind head on master.

Additional details and impacted files
@@             Coverage Diff              @@
##             master    #4112      +/-   ##
============================================
- Coverage     86.03%   86.03%   -0.01%     
  Complexity     1449     1449              
============================================
  Files          1248     1248              
  Lines        195841   195841              
  Branches     161139   161140       +1     
============================================
- Hits         168501   168500       -1     
- Misses        23206    23208       +2     
+ Partials       4134     4133       -1     
Components Coverage Δ
Rust Core 86.95% <ø> (ø)
Java SDK 67.54% <ø> (ø)
C# SDK 76.99% <ø> (-0.02%) ⬇️
Python SDK 91.33% <ø> (ø)
PHP SDK 85.65% <ø> (ø)
Node SDK 96.23% <ø> (-0.02%) ⬇️
Go SDK 69.43% <ø> (+0.03%) ⬆️
see 5 files with indirect coverage changes
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@RustToMetal

Copy link
Copy Markdown
Author

Hi @hubcio @slbotbm, please see: #4190. Once this is reviewed, I will open other PRs chronologically.

@github-actions github-actions Bot removed the S-waiting-on-review PR is waiting on a reviewer label Sep 15, 2026
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.

Add Swift SDK for Apache Iggy

4 participants