Server-side Swift has been an exciting prospect ever since Apple officially released an open source Linux-compatible version. My curiosity finally got the better of me, and it was time to give it a try.
Aside from a few mBaaS experiments, I hadn’t had any backend experience, but thankfully the Open Source Community had already been hard at work building libraries. I spent some time with several of them before deciding on Vapor, by Tanner Nelson. I chose Vapor because it had the most straightforward setup, it was well suited to my task, and it specified Heroku in the docs. I picked Heroku, a popular Platform as a Service (PaaS), because that’s what our backend team uses, and it has a pretty user-friendly front end.
Going forward, if you’re going to follow along, you’ll need a Heroku account and an install of the Swift Development Snapshot. At the time of writing, the Swift package manager isn’t included in the release, which is why you’ll need to download the development snapshot.
The goal was to get a simple Swift server up and running on Heroku that could say “hello.” Having never worked in a Linux environment, it made sense to start off locally. This meant setting up a local Xcode project and configuring it to run with the Swift package manager. This involves 4 main steps:
Move main.swift file to 'Souces' folder in top-level directory
Add Package.swift file
Add .build directory to import paths
To get code completion and syntax highlighting with our imported libraries, the Swift Package Manager build directory needs to be added to the import paths. Make sure to import the 'debug' folder for the 'debug 'configuration and 'release' for 'release.'
Run Xcode from toolchain
If you’re on Xcode 7.3, you can also go to Xcode > Toolchains to open an instance of Xcode that utilizes a Swift snapshot. It’s important to note that even with these additions, we are still unable to build within Xcode. To compile we have to use 'Swift build' from the command line.
Creating the Server
I was pleasantly surprised by how few lines of code I had to write to get a proof of concept ready. In fewer than 10 lines of code, I was up and running.
From there it’s a one line command on the terminal to get up and running.
Things were looking good so far, but I needed to check it in a browser. The response on your screen might look a little different, I use this JSON formatter plugin.
To The Cloud
Things were pretty smooth getting set up locally, but it’s a far better test to hit a remote endpoint. I was eager to get the app up into the proverbial cloud. This was really uncharted territory for me, but luckily some awesome guidance from Vincent Toms helped me get started.
Heroku setup was a surprisingly pleasant experience, and in a few moments, I had a Heroku app setup, my toolbelt was installed, and I was ready to push up my project.
I anticipated it couldn’t be that easy, so I went back to the Vapor docs and eventually landed on these newfangled things called buildpacks. Heroku provides some standard buildpacks out of the box, but doesn’t yet have anything for Swift. Yet again, the amazing Open Source Community came to the rescue, this time in the form of Kyle Fuller’s buildpack. Getting it integrated was simple.
With the buildpack setup and the app loaded successfully, it was time to visit the real world URL.
It couldn’t have been that easy, could it? After a bit of Googling and a closer look at some examples I found out that I need a Procfile. Based on the contents, the intent of the file is pretty clear.
The buildpack was creating the executable, but Heroku didn’t know about it. With the Procfile we’re able to tell Heroku to run the 'SwiftServerIO' executable. Time to push up the Procfile.
More Failure Pt. 2
The two minutes for Heroku to build seemed like forever, and I quickly reloaded my browser only to find more of this.
I thought maybe Heroku takes a few minutes to get started (it doesn’t), so I waited a while before realizing something was still not working. The executable was up, the process file was ready, but something was still off. Another round of Googling commenced until I eventually ended up learning that you need to scale up the app. This involves a simple command to the Heroku toolbelt.
heroku ps:scale web=1
Heroku only gives you one dyno for free, but that’s plenty for our simple server. With that, the dynos are officially running. Time to check the browser again.
It worked! The server was up and running with the ubiquitous “hello world”! After a copious round of self congratulation and celebration, it was time to say hello.
Making the server give a more personal hello involved a small addition to our 'main.swift' file. By adding another get route that takes a slug, the server can use that input to say hello back.
Everything should still work, but given the usual nature of development, I prepared myself for another round of errors. The change was committed, and it was time to push it back up to Heroku.
The configurations stood the test of time and adding to my hello server was as simple as pushing up to Heroku. After a minute or so build time, the URL was active and the server was saying hello. Check it out yourself.
If what I’ve seen so far is any indication, there’s going to be a strong effort from the community to add tons of support for server-side Swift. For me, getting real JSON from a live remote endpoint was an exciting first step into this world, and I can’t wait to see what comes next.
You can check out the source code with nicely spaced commits here.
There’s also a Journal folder in the directory with step by step instructions included.
More helpful links: Server Side Swift!