Contributing to the Server-side Swift World

Petr Pavlík
The Swift Web Developer
5 min readOct 10, 2016

With Swift 3 out and several major server-side swift frameworks being in a very reasonable state, I fell like the time has finally come to start taking server-side Swift development more seriously. This article will show you how easy it is to contribute to the ecosystem by creating a simple but very useful package.

Let’s say that I need to measure distance between 2 locations on the server. I know from my iOS dev background that there is a class called CLLocation, which has a method exactly for that. Now the issue is that CLLocation is a part of CoreLocation framework and there is currently no CoreLocation on Linux, so I’m sentenced to writing my own implementation.

We should probably first have a look whether there already is a package that would help with this. The best way is to check out swiftpack at http://swiftpack.co or swift package catalog at https://swiftpkgs.ng.bluemix.net, which does not seem to return anything like this.

Ok, this might be a good way to contribute to the environment. Let’s do a reality check and have a look at the stats of npm package called geolib, which serves the same purpose in the node.js world.

  • Downloads today: 612
  • Downloads last month: 32 491

Well, that looks promising. Let’s do this and leverage the features of Swift language while doing so. This is what I came up with:

do {    let prague = try GeoCoordinate2D(latitude: 50.0880400,    
longitude: 14.4207600)
let brno = try GeoCoordinate2D(latitude: 49.195060, longitude:
16.606837)

let distancePragueBrnoInMeters = prague.distance(from: brno)

print("Distance between Prague and Brno is \
(distancePragueBrnoInMeters * 0.00062137) mi.")
} catch {
// Tried to create an instance of `GeoCoordinate2D` with invalid
// coordinates.
}

What I personally find really useful is that you simply cannot create/alter an instance of GeoCoordinate2D with invalid coordinates, all thanks to Swift. Not let me show you how GeoSwift came to be.

Create a Swift Package

Creating a new package is super easy once you have Xcode 8 installed on your machine. You can simply install it via Mac App Store if you don’t. I know that this may sound unbelievable to say node.js developers, but really, just install Xcode and you’re good to go. No config files, no plugins, no nothing.

Let’s fire up the terminal:

mkdir GeoSwift
cd GeoSwift
swift package init

This generates the project structure for your package and names it by the name of parent directory, GeoSwift in my case.

.
├── Package.swift
├── Sources
│ └── GeoSwift.swift
└── Tests
├── GeoSwiftTests
│ └── GeoSwiftTests.swift
└── LinuxMain.swift

Here is what generated Package.swift looks like. I didn’t need to make any changes to this file.

import PackageDescription

let package = Package(
name: "GeoSwift"
)

Write the Code

I don’t know about you, but do find Xcode quite convenient, so let’s generate an Xcode project for the package.

swift package -generate-xcodeproj

.gitignore generated when new package was initialized includes the Xcode project file so it won’t be pushed to the repo. Let’s keep it that way.

I’ve chosen TDD approach in this case by writing the unit tests first and testing the source code by running the unit tests in Xcode (cmd + u).

Please have a look at the structure of GeoSwift’s repo for more information. Just clone the repo and generate Xcode project.

How About Linux

You should be able to easily test whether such a simple piece of code works fine on Linux simply by running it through IBM’s Swift sandbox available at https://swiftlang.ng.bluemix.net/#/repl. I’ll describe how to run CI on Linux later on in this article.

In case you wanted to develop the whole thing on Linux, you can by using comands like swift build and swift test in the terminal instead of using Xcode since there is no Xcode on Linux.

Publish The Package

Simply push your your code to a public github repo and tag it with 1.0.0 or whatever release number you feel like.

You may also want to submit your package to IBM’s swift package catalog to make it easier for other developers to find it.

You should also add a description for each release on github, it works well with the package catalog.

Use the Package

Package.swift file of every server-side Swift project, being it a library or an executable, contains a section dependencies. Simply add GeoSwift to the dependencies of your project and launch swift package update in the terminal. You’ll need to re-generate the Xcode project after you update the dependencies of your project.

.Package(url: "https://github.com/petrpavlik/GeoSwift.git", majorVersion: 1)

This will update the package to the latest 1.x version each time you launch swift package update.

You can easily change the address to your forked repo in case you have found and fixed a bug.

Making Sure it Actually Works

Remember that “build passing” icon on many github repositories? You can and should have that as well, especially to make sure your package works fine on Linux. Travis is here to help, they provide free continous integration for open source projects, much like github provides free public git repositories.

The setup is actually super simple

  • Add .travis.yml to the root of your repo with content described bellow.
  • Sign up for Travis and add the repository you want to have tested
  • Profit. Travis will compile your source code and run unit tests on both macOS and Ubuntu each time you push to the repository or merge in a pull request, and notify you about the result. I have personally found that Linux part extremely useful when building my packages since there are slight differences, even bugs unfortunaely, in the open source implementation of Foundation.

Content of .travis.yml:

os:- linux- osxlanguage: genericsudo: requireddist: trustyosx_image: xcode8script:- eval "$(curl -sL https://swift.vapor.sh/ci)"- eval "$(curl -sL https://swift.vapor.sh/codecov)"

As you can see, I hooked up to vapor’s scripts for continuous integration and code coverage so I don’t have to update mine when swift 3.1 is out or whatever.

Those fancy badges for your repo? You can just open readme.md of GeoSwift and copy paste them to your readme.md, just remember the change the paths to your repository.

Your turn

There a huge opportunity to make your name in the community simply by bringing a popular package wrom Node.js or Ruby world to server-side swift world so, yeah, you might want to give it a shot.

ps: I recently launched a catalog of server-side Swift packages http://swiftpack.co, which automagically crawles github for packages that support Swift on backend.

Subscribe to Swift Web Weekly!

If you’re interested in web development with Swift, Swift Web Weekly is a free newsletter Gianluca Tranchedone is curating with interesting links related to server-side Swift, HTML, CSS, JavaScript, tools and more. If you don’t like it you can unsubscribe at any time, so why don’t give it a try?! 🙂

--

--