NIOClientTCPBootstrap

    NIOClientTCPBootstrap is a bootstrap that allows you to bootstrap client TCP connections using NIO on BSD Sockets, NIO Transport Services, or other ways.

    UniversalBootstrapSupport.swift:144
    struct NIOClientTCPBootstrap

    Usually, to bootstrap a connection with SwiftNIO, you have to match the right EventLoopGroup, the right bootstrap, and the right TLS implementation. Typical choices involve:

    • MultiThreadedEventLoopGroup, ClientBootstrap, and NIOSSLClientHandler (from swift-nio-ssl) for NIO on BSD sockets.

    • NIOTSEventLoopGroup, NIOTSConnectionBootstrap, and the Network.framework TLS implementation (all from swift-nio-transport-services.

    Bootstrapping connections that way works but is quite tedious for packages that support multiple ways of bootstrapping. The idea behind NIOClientTCPBootstrap is to do all configuration in one place (when you initialize a NIOClientTCPBootstrap) and then have a common API that works for all use-cases.

    Example:

    // This function combines the right pieces and returns you a "universal client bootstrap"
    // (`NIOClientTCPBootstrap`). This allows you to bootstrap connections (with or without TLS) using either the
    // NIO on sockets (`NIO`) or NIO on Network.framework (`NIOTransportServices`) stacks.
    // The remainder of the code should be platform-independent.
    func makeUniversalBootstrap(serverHostname: String) throws -> (NIOClientTCPBootstrap, EventLoopGroup) {
        func useNIOOnSockets() throws -> (NIOClientTCPBootstrap, EventLoopGroup) {
            let group = MultiThreadedEventLoopGroup(numberOfThreads: 1)
            let sslContext = try NIOSSLContext(configuration: TLSConfiguration.forClient())
            let bootstrap = try NIOClientTCPBootstrap(ClientBootstrap(group: group),
                                                      tls: NIOSSLClientTLSProvider(context: sslContext,
                                                                                   serverHostname: serverHostname))
            return (bootstrap, group)
        }
    
        #if canImport(Network)
        if #available(macOS 10.14, iOS 12, tvOS 12, watchOS 3, *) {
            // We run on a new-enough Darwin so we can use Network.framework
    
            let group = NIOTSEventLoopGroup()
            let bootstrap = NIOClientTCPBootstrap(NIOTSConnectionBootstrap(group: group),
                                                  tls: NIOTSClientTLSProvider())
            return (bootstrap, group)
        } else {
            // We're on Darwin but not new enough for Network.framework, so we fall back on NIO on BSD sockets.
            return try useNIOOnSockets()
        }
        #else
        // We are on a non-Darwin platform, so we'll use BSD sockets.
        return try useNIOOnSockets()
        #endif
    }
    
    let (bootstrap, group) = try makeUniversalBootstrap(serverHostname: "example.com")
    let connection = try bootstrap
            .channelInitializer { channel in
                channel.pipeline.addHandler(PrintEverythingHandler { _ in })
            }
            .enableTLS()
            .connect(host: "example.com", port: 443)
            .wait()

    See also

    Citizens in NIOCore

    Type members

    Instance members