Traversio

Opening A Client

Start the SFTP subsystem and inspect the negotiated version and extensions.

Open The Client

The public SFTP entry point is SSHConnection.openSFTP(clientVersion:).

import Traversio

@available(macOS 26.0, iOS 26.0, *)
func openSFTP(configuration: SSHClientConfiguration) async throws {
    try await SSHClient.withConnection(configuration: configuration) { connection in
        let sftp = try await connection.openSFTP()
        let exchange = try await sftp.currentVersionExchange()

        print(exchange.clientVersion)
        print(exchange.serverVersion)
    }
}

The default client version is 3, which matches the current implementation focus.

Inspect Extensions

SSHSFTPVersionExchange exposes the extensions advertised by the server:

let exchange = try await sftp.currentVersionExchange()

print(exchange.extensions.map(\.name))
print(exchange.supportsExtension(named: "[email protected]", minimumVersion: 1))

Traversio automatically prefers [email protected] when the server advertises version 1 or later. Otherwise it uses standard SSH_FXP_RENAME.

Close The Client

SFTPClient.close() closes the subsystem channel explicitly:

let connection = try await SSHClient.connect(configuration: configuration)
let sftp = try await connection.openSFTP()

let exchange = try await sftp.currentVersionExchange()
print(exchange.serverVersion)

try await sftp.close()
await connection.close()

If you opened the client inside SSHClient.withConnection(...), the enclosing connection scope invalidates the SFTP client automatically. Explicit close() is useful when you manage a long-lived SSHConnection and want to release the subsystem channel early.

Behavior And Limits

Opening the client:

  • opens a subsystem channel
  • requests sftp
  • performs the initial version exchange
  • keeps the resulting actor scoped to the enclosing connection lifetime

The current surface focuses on the subsystem lifecycle and version negotiation. Larger transfer features remain outside this page:

  • handle-level stream-style upload/download helpers, which are documented on Transfers
  • resumable whole-file upload/download helpers, whole-file transfer progress callbacks, and bounded concurrency controls, which are documented on Transfers
  • automatic reconnect behavior
  • a separate long-lived lifecycle outside withConnection

On this page