Skip to content

fix: update Swift protobuf codegen to match SDK runtime - #2052

Merged
tbarbugli merged 2 commits into
mainfrom
fix/swift-protobuf-codegen
Sep 16, 2026
Merged

tbarbugli merged 2 commits into
mainfrom
fix/swift-protobuf-codegen

Conversation

@martinmitrevski

Copy link
Copy Markdown
Contributor

Problem

protoc-gen-swift is pinned to 1.22.0 (install.sh), but stream-video-swift links SwiftProtobuf 1.38.1. Every regeneration therefore emitted code that fails Swift 6 builds, and the iOS team hand-patched it afterwards — patches that were wiped by the next regen:

  • static var allCases instead of static let → "static property is not concurrency-safe"
  • _StorageClass with no Sendable handling → hand-patched in the iOS SDK's Swift 6 migration
  • deprecated init(serializedData:) instead of init(serializedBytes:)

Separately, the Swift twirp template had drifted badly from what the iOS SDK maintains by hand on top of the generated signal.twirp.swift — so those edits also had to be re-applied every time.

Changes

versions.sh — new PROTO_SWIFT_VERSION=1.38.1, alongside the other pinned tool versions, with a note that it must track the SwiftProtobuf runtime the consuming SDKs link.

install.sh — use that variable instead of the hardcoded 1.22.0.

tools/protoc-gen-swift-twirp/generator/template.goswift — brought in line with the hand-maintained client: retry handling via HTTPConfig, Response: ProtoModelResponse with hasError checks, the X-Stream-Client header, serializedBytes, and 4-space indentation.

1.38.1 emits nonisolated struct ...: @unchecked Sendable on messages and static nonisolated(unsafe) let defaultInstance, so Swift 6 is satisfied at the struct level and the hand-patched _StorageClass: @unchecked Sendable is no longer needed.

Verification

Built protoc-gen-swift 1.38.1 and the updated twirp plugin locally, regenerated video/sfu, dropped the output into stream-video-swift, and built StreamVideo for iOS Simulator: BUILD SUCCEEDED, zero errors and zero warnings from generated code. Diffing the new signal.twirp.swift against the hand-maintained one shows no semantic differences — only sendMetrics (genuinely new in the proto) and update(userToken:) moving below the generated methods.

Follow-ups for the iOS SDK (not in this PR)

  • SendMetricsResponse is an empty message with no error field, so it can't satisfy ErrorProviding like the other responses. It needs an explicit conformance in ProtoModel.swift before the regenerated code compiles.
  • That ErrorProviding list is hand-maintained, so every new RPC breaks the iOS build until someone adds a line. Worth considering having the template generate these conformances.

Rollout

Both changed files are baked into the Docker image at build time (Dockerfile does COPY . /home/ + RUN ./install.sh, and the template is go:embeded). So this needs to land on maindocker-image.yml rebuilds ghcr.io/getstream/protobuf-generate:latestScripts/generateCode.sh on the SDK side picks it up. Anyone with an existing /opt/.protoc install must re-run install.sh to get the new plugins locally.

🤖 Generated with Claude Code

martinmitrevski and others added 2 commits September 16, 2026 16:38
protoc-gen-swift was pinned to 1.22.0 while stream-video-swift links
SwiftProtobuf 1.38.1, so every regeneration emitted code that fails Swift 6
builds and had to be hand-patched afterwards:

- `static var allCases` instead of `static let` (concurrency-safety warning)
- `_StorageClass` without Sendable handling (the iOS SDK patched this by hand
  in its Swift 6 migration)
- deprecated `init(serializedData:)` instead of `init(serializedBytes:)`

Pin the plugin to 1.38.1 via a new PROTO_SWIFT_VERSION in versions.sh,
alongside the other pinned tool versions. 1.38.1 emits
`nonisolated struct ...: @unchecked Sendable` on messages and
`static nonisolated(unsafe) let defaultInstance`, so the hand-patched
`_StorageClass: @unchecked Sendable` is no longer needed.

The Swift twirp template had also drifted from what the iOS SDK maintains by
hand on top of the generated file. Bring it in line: retry handling via
HTTPConfig, `Response: ProtoModelResponse` with `hasError` checks, the
X-Stream-Client header, `serializedBytes`, and 4-space indentation.

Verified by regenerating video/sfu with the new plugin and template and
building StreamVideo for iOS: no errors, no warnings from generated code.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@tbarbugli
tbarbugli merged commit 802d449 into main Sep 16, 2026
5 checks passed
@tbarbugli
tbarbugli deleted the fix/swift-protobuf-codegen branch September 16, 2026 22:38
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.

2 participants