Taylor: The Most Un-Googleable Swift Library

There are many programming topics that developers are familiar with, but don’t truly understand. As an example in self education, the young developer Jorge Izquierdo tackles one of his own, by writing an HTTP server library in Swift, called Taylor. Employing advice from Ayaka Nonaka’s Summit talk on Swift Scripting, he ends by implementing a command-line interface, and reveals that his slides are being served by Taylor itself.

You can view Jorge’s project on GitHub.


Taylor, an HTTP Server Library (0:00)

Today I’m going to be talking about Taylor, an HTTP server library. I wrote it this summer while I was in Hacker School, which is a three month programmer retreat focusing on self-learning. One of their mantras includes “Tackle your black boxes!” — software whose side effects you are familiar with, although you don’t actually know how it works. For some people their black box was the compiler, but for me it was something as seemingly simple as an HTTP server.

An HTTP is a really simple protocol. It just runs on TCP, a protocol that takes charge of managing the packages that are getting sent and received. In the request, you have one method and a resource, along with headers. The response is similar to the request, but has a status code that signals whether the request has succeeded or failed. Then, the response will give you the data.

Flow in Taylor (1:22)

After reading the implementation of other HTTP servers, I decided to organize the flow in Taylor around handlers. A handler is a piece of code, a closure in Swift, that takes a request, response, and a callback. After performing some actions, the flow either continues on to the next handler, or sends the response. The response body is generated and sent over the network.

Swift Types in Taylor (2:00)

In Taylor, I have a Swift enum named Callback. Its cases are Continue and Send, both of which take a Request and a Response. We have also the idea of a Handler, which takes a Request, a Response, and a Callback.
```swift enum Callback { // Looking for a better term case Continue(Request, Response) case Send(Request, Response) }

typealias Handler = (Request, Response, (Callback) -> ()) -> () ```

A really simple example of a handler could be this requestLogger. A request logger takes a request and a response, and prints to a printer that it is just a function that takes a string. It brings to the printer the status of the request. In this case, it will print the timeDelta, which is the time it took for the whole request to be processed, as well as a timeString and a text. Then it will continue with the next handler.

There is also a special handler called the Router. This router takes a number of routes that have an HTTP method. These can be get, post, or put. An example for a route would be this block of code. On post to the resource /hi/:name, it will go first to the handler Taylor.Middleware.bodyParser to parse the body of the HTTP request. It will send, in the response body string, the name and the age you get from the body. The last thing it sends is the callback, the request and the response.
```swift server.post(“/hi/:name”, Taylor.Middleware.bodyParser(), { request, response, cb in

if let name = request.parameters["name"],
    let age = request.body["age"] {
        response.bodyString = "\(name) is \(age) years old"
}

cb(.Send(request, response)) }) ```

Demo (3:34)

This presentation, hosted on my website here, runs with Taylor. Another example server that I have written has two handlers. One is for the static directory; when it gets a request in /talk, it maps with a file in NSBundle.mainBundle. Then, it has a request logger that gives any request XCPCaptureValue. That is a way of telling the Playground to see all the requests that are in the talk.

One thing that motivates me to create a web server in Swift is the fact that you can use all Apple frameworks. Another example I have involves Core Image. On this server, we can apply a Core Image filter to a picture. After selecting the filter from a list, the server will apply the filter and return an image of the result.

After Ayaka’s talk yesterday, I wanted to make Taylor work with her method of Swift scripting. So, now you can run Taylor from the command line. I have a server that imports Taylor and takes the framework from either Rome or Carthage. Then you can go and run the server, and do a request when it is ready.

In Conclusion (6:04)

The cool things about this is that you can use all Apple frameworks in your HTTP server. You can also do live coding with an HTTP server in the Playground. However, there is the problem that we lack the infrastructure to run this in the cloud. Since it is written in Swift, Taylor only works on OS X, 10.9 and superior.

I used CocoaAsyncSocket as the TCP library for Taylor. My library is also heavily inspired by ExpressJS and Go’s server Martini.

Thanks.

Q&A (6:44)

Q: I wanted to comment on something I noticed. A very cool use for Taylor would be to use it as a workaround for WKWebView. When you cannot load things from the app bundle, you could set up on your iPhone a webserver that just serves things from the local bundle. It would then use WKWebView to actually hold it.

Jorge: Yes, totally! You can also use Taylor embedded in your application to deploy an HTTP server from inside your application.



Jorge Izquierdo

Jorge Izquierdo