TCP Server With the SwiftNIO Networking Framework

Mobile developers often work with REST APIs or other networking protocols in their applications to access data or to coordinate activities. In this tutorial you will create a Swift Server with SwiftNIO, a low-level networking framework that makes creating TCP servers easier than before. By David Okun.

Leave a rating/review
Download materials
Save for later
You are currently viewing page 3 of 3 of this article. Click here to view the first page.

Polishing Off Your Server Functionality

In Xcode, go back to QuoteServer.swift and, in between your init(host:port:) method and your serverBootstrap var, add the following:

// 1
func run() throws {
  // 2
  guard let host = host else {
    throw QOTDError.invalidHost
  guard let port = port else {
    throw QOTDError.invalidPort
  do {
    // 3
    let channel = try serverBootstrap.bind(host: host, port: port).wait()
    print("\(channel.localAddress!) is now open")
    try channel.closeFuture.wait()
  } catch let error {
    throw error

Breaking down what you’ve done:

  1. You don’t want to put this code inside init(host:port:) method because it’s not ideal to let code that runs “forever” reside in a constructor. This makes it easy to debug issues, too.
  2. You check for port and host using two guard statements.
  3. With values for host and port ensured, you bind the ServerBootstrap instance you create in this class to a host and port that you specify. Calling wait() at the end of this means you’re waiting for the “promise” to be fulfilled. This means you’re waiting for your server to start.

Poetic as it sounds, you can’t run forever; you need a graceful way to shut down your server. In the same class, after run(), add the following:

func shutdown() {
  do {
    // 1
    try group.syncShutdownGracefully()
  } catch let error {
    print("Could not shutdown gracefully - forcing exit (\(error.localizedDescription))")
    // 2
  print("Server closed")

Here’s what you’ve just added:

  1. You try the friendly API for the MultiThreadedEventLoopGroup for shutting down without causing any issues. This means it’ll wrap up any last tasks it might have to execute, and then it shuts itself down.
  2. Of course, if that just won’t fly, you hit the power button yourself and shut down the server “un-gracefully.”

Running Your Server

You’ve got yourself a server! Only one more change before we run it.

In Xcode, open main.swift. Delete the lone print statement at the bottom and replace it with the following:

// 1
let server = QuoteServer(host: "localhost", port: 1717)
do {
  // 2
} catch let error {
  print("Error: \(error.localizedDescription)")
  // 3

And here’s what this code does:

  1. You create an instance of your server, passing host and port.
  2. You run your server. Note, if this call works successfully, which it should, then the application will run infinitely until you shut it down or until something breaks.
  3. You check for any errors and, if you detect any, you make use of your handy-dandy shutdown() method.
Note: Remember you might not want to start your server from inside the constructor? The above code is a great example of this. A separate run() method allows us to make changes to other properties of your server before running it.

Build and run your project. You should see a line in the debugger about your server being open on port 1717.

Pull your iOS client back up. Build and run it if you stopped the project. Tap the refresh button and…

Voilà! A quote.

Voilà! A quote.

Your Swift TCP server is running! Check the logs on your Xcode project running your debugger and you should see the following output:

Incoming connection registered - sending Quote of the Day
Sending quote
Closing connection

Where to Go From Here?

You can download the final project using the link at the top or bottom of this tutorial. I encourage you to build on this and play with the available APIs to see what else you can do.

Additionally, if you clone the SwiftNIO project from source, there are a couple of demos you can try right inside the project itself. If you open Xcode, you can see the executables listed in the scheme selector:

Try running some of these executables either from Xcode or the command line.

For more information on SwiftNIO from Apple itself, check out the full Apple SwiftNIO Docs on Apple’s GitHub.

It’s an exciting time for Swift as it stretches past mobile development and into the rest of the programming world. Let us know what Swift projects you’re working on, your thoughts on the future of Swift, or leave us your favorite Quote of the Day in the forum discussion below!