swift client sdk#613
Open
rebornix wants to merge 3 commits intomicrosoft:mainfrom
Open
Conversation
Adds a pure Swift implementation of the Dev Tunnels client SDK,
supporting iOS 16+ and macOS 13+.
Features:
- Tunnel management API (list, create, get, update, delete)
- Tunnel port management (create, delete)
- Relay client connections over WebSocket + SSH
- Auto-reconnect with configurable backoff
- Device code authentication flow
- SSH keepalive ping scheduling
- Client-side tunnel ID generation (matching official SDK format)
Built on SwiftNIO for async networking and NIOSSH for the SSH layer.
158 unit tests (all offline using mocks), plus 2 live integration
tests gated behind DEV_TUNNELS_TOKEN environment variable.
SPM requires Package.swift at the repository root to resolve dependencies. The root manifest uses explicit paths to reference swift/Sources/ and swift/Tests/, similar to how go.mod sits at root for the Go SDK. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
DavidObando
added a commit
that referenced
this pull request
Apr 29, 2026
1. Remove duplicate inner swift/Package.swift; keep root Package.swift as the single SPM manifest. 2. swift.yml: bump actions/checkout to v4; split CI into a default 'build' job that runs unit tests only (--skip IntegrationTests) and a manually-dispatched 'integration' job that requires DEV_TUNNELS_TOKEN. Also drop 'cd swift &&' since the package now lives at the repo root. 3. TunnelRelayConfig.authorizationHeader: use case-insensitive hasPrefix instead of substring contains, so tokens whose body contains 'tunnel' get the 'Tunnel ' scheme prepended correctly. Also trim surrounding whitespace. 4. SSH host key validation: add a public hostKeyValidator hook on TunnelRelayConfig that receives the NIOSSHPublicKey. Default behavior (nil validator) still accepts any key for parity with the Go SDK's InsecureIgnoreHostKey, but the security caveat is now documented loudly on the public API and callers can pin keys via NIOSSHPublicKey's Hashable conformance. 5. TunnelRelayStream: stop calling syncShutdownGracefully() from deinit (deadlocks when deinit runs on one of the group's event loops). Document that close() is required and best-effort cancel keepalive in deinit only. TunnelRelayClient.disconnect() still returns synchronously but a new disconnectAsync() awaits the underlying close so callers can wait for the EventLoopGroup to release. 6. PortForwardMessages.readString: use Int(exactly:) to guard against UInt32 -> Int overflow on 32-bit platforms / hostile peers declaring absurdly large string lengths. 7. TunnelRelayClient.waitForDisconnect: check terminal state and stash the continuation under the same lock that disconnect / wireDisconnect use to wake it, removing a race where a disconnect could resume an empty slot before the waiter stashed its continuation. 8. WebSocketBinaryFrameHandler: surface incoming pong frames via a new onPong callback. TunnelRelayStream now tracks unanswered pings and closes the parent channel after maxUnansweredPings (2) consecutive missed pongs, detecting half-dead peers. 9. Replace force-unwraps: TunnelManagementClient.generateTunnelId now uses ?? fallbacks; ManagementClientTests now uses XCTUnwrap on request URLs and a fallback URL in the mock client. Adds unit tests covering the auth header substring regression, the overflow-rejecting readString, the host key validator (accept / reject paths), and pong frame handling. All 163 unit tests pass.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #612
This is my experiment for a swift package to be used in an iOS/macOS client. Added unit tests and integration tests for the package as well.
Changes proposed:
Other Tasks:
npm view @microsoft/dev-tunnels-contracts). This will fix issues where yarn will pull the old version of packages and will cause mismatched dependencies. See example PR