Article

Introduction to SwiftPoet

Sean Berry

July 2, 2018

SwiftPoet is a powerful framework built by Gilt Tech to let you generate your own Swift code… using Swift!

Why do this? Sometimes the job of a developer is to crank out some boilerplate code. It’s not all brilliant problem solving. Developers are great at recognizing patterns, and if it’s possible to automate something, we’ll do it.

I’m using SwiftPoet in a command line tool to translate Avro schema definitions into Swift structs that are customized to my liking. (To make your own — check out my article on how to setup a Swift Command Line Tool with a dependency .)

For reference, there is an API doc , but it doesn’t show you how to get started. I aim to rectify that in this article.

The goal is to generate a String

Ultimately we want to generate some Swift code. SwiftPoet provides that to us in String form.

To do that, create a PoetFile object and retrieve the generated Swift through the fileContents property:

Not very exciting so far. To make it do anything interesting we need to give the PoetFile some PoetSpecs.

A PoetSpec is used to represent every bit of Swift you can think of.

Want to generate a struct? Check out StructSpec. How about a field? They got you withFieldSpec. A parameter is what you’re asking for? Use ParameterSpec. (I hope you see the pattern.)

Here’s the thing, you can’t use them directly.

Builder pattern

There aren’t any public initializers for the specs! Try going StructSpec() (it won’t work).

Instead, each spec has a static builder method that returns a corresponding <type>Builder for you to use. E.g. StructSpec.builder(for: “MyStruct") returns a StructSpecBuilder.

You then call the various add methods on the StructSpecBuilder to give it whatever characteristics you want, say, a field!

This is where it gets a bit… verbose. To add a field, you need to create a builder first and then build it.

As you can see, when you add a field to a structor class, you get it added to the default initializer method for free!

The other key thing to learn is TypeName . This is where you park your type data. You can create one manually with TypeName(keyword: "MyType") but they also provide a bunch of static values for common primitives.

CodeBlocks

CodeBlocks let you manually specify what the code will look like. To make your life easier, SwiftPoet provides you with a handy extension on String called .toCodeBlock().

Let’s add a method to our struct:

Swift’s multi-line string syntax really comes in handy when you’re writing code that writes code!

Final Example

Let’s bring it all together by adding a parameter to our method and providing some default values.

Note — we need to make our field a var to simultaneously give it a default value and allow it to be set in our initializer. Can you figure out how I changed it from let to var?

Hint: look at `construct`

That should be enough to get you started! Hit me up @regularberry if you need any additional help.

Thanks a ton to the Gilt team for open sourcing this project!

Sean tries to automate himself out of a job at Livefront .
  • Sean Berry

    Software Engineer

    Sean Berry