Skip to content

swift client sdk#613

Open
rebornix wants to merge 3 commits intomicrosoft:mainfrom
rebornix:rebornix/swift-client-sdk
Open

swift client sdk#613
rebornix wants to merge 3 commits intomicrosoft:mainfrom
rebornix:rebornix/swift-client-sdk

Conversation

@rebornix
Copy link
Copy Markdown
Member

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.

dev-tunnels-swift % DEV_TUNNELS_TOKEN="github ghu_" swift test --filter IntegrationTests
Building for debugging...
[1/1] Write swift-version--58304C5D6DBC2206.txt
Build complete! (0.17s)
Test Suite 'Selected tests' started at 2026-04-09 21:05:29.473.
Test Suite 'DevTunnelsClientPackageTests.xctest' started at 2026-04-09 21:05:29.474.
Test Suite 'IntegrationTests' started at 2026-04-09 21:05:29.474.
Test Case '-[DevTunnelsClientTests.IntegrationTests testListTunnels]' started.
Test Case '-[DevTunnelsClientTests.IntegrationTests testListTunnels]' passed (2.746 seconds).
Test Case '-[DevTunnelsClientTests.IntegrationTests testTunnelCRUDLifecycle]' started.
Test Case '-[DevTunnelsClientTests.IntegrationTests testTunnelCRUDLifecycle]' passed (4.721 seconds).
Test Suite 'IntegrationTests' passed at 2026-04-09 21:05:36.943.
         Executed 2 tests, with 0 failures (0 unexpected) in 7.467 (7.468) seconds
Test Suite 'DevTunnelsClientPackageTests.xctest' passed at 2026-04-09 21:05:36.943.
         Executed 2 tests, with 0 failures (0 unexpected) in 7.467 (7.468) seconds
Test Suite 'Selected tests' passed at 2026-04-09 21:05:36.943.
         Executed 2 tests, with 0 failures (0 unexpected) in 7.467 (7.469) seconds

Changes proposed:

  • Add swift client package

Other Tasks:

  • If you updated the Go SDK did you update the PackageVersion in tunnels.go
  • If you updated the TS SDK did you update the dependencies in package.json for connections and management to require a dependency that is > the current published version(Found using 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

rebornix and others added 3 commits April 9, 2026 21:21
    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.
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.

Feature request: swift client sdk

1 participant