قالب وردپرس درنا توس
Home / IOS Development / # 292: Metaprogramming with Sourcery 🔮 – Little Bites of Cocoa

# 292: Metaprogramming with Sourcery 🔮 – Little Bites of Cocoa



Subjects

Topics

We cover many libraries and development tools here at LBOC . Many are useful not only on their surface but also as to how they allow us to learn from our employees.

Throughout this process, we collectively explore new approaches and techniques. New ideas appear all the time.

Once upon a time, one of these ideas stands out.

Sometimes an idea gives too much meaning, or is it just too useful to ignore.

In modern times like Fastlane, CocoaPods and Carthage comes in mind. A little more experienced people can remember the advent of Pull to Refresh, or BWToolkit.

Sourcery from Krzysztof Zabłocki is the last addition to this set.

It brings the term "meta-programming" to Swift, and it's

the core box in our crystal ball and see what it can do.

The kernel generates Sourcery Swift code from template files .

It combines elegantly two other great development tools: SourceKitten (for code depiction) and Stencil (for templates).

It aims to solve some issues:

  • Reduce time used to write so-called "boilerplate", or repeat / clear code.
  • Provide a way to explain the types of our code and their properties.
  • Reduce simple human errors, caused by things like typos.

Okay enough introduction. Here's how Sourcery works:

  • First, we'll write some code that sees almost as usual Swift code into "template" ( .stencil ) files.
  • Then we run sourcery command line tool. This will "render" our .stencil files to .swift files that we add to our project.
  • When we build our app, our "generated" .swift files will be aggregated as any other .swift files we can add.

Immediately, some ideas about how to use this are beginning to think about. Here are some specific tasks that can make us come to Sourcery:

  • In accordance with our types for NSCoding .
  • In accordance with Equatable or Hashable
  • Write the JSON de-serialization code

Maintenance of each of these implementations is an infinite task. When we add, remove or change a property, we may need to revise each of these tags as well. Bummer.

Ok. Let's try this thing.

First, we need to get the command line tool sourcery . The easiest way to do this is to download the latest version binary here.

Leave cd into the root directory of the download and copy the tool to a place permanently:

  cp bin / sourcery / usr / local / bin

(Note: / usr / local / bin is a common place to put command line tools on macOS thanks to the fact that Homebrew puts things there, so it's probably already in our $ 1

9459025 $ PATH ).

Neat. Now we can use it anywhere.

We could also have copied the tool to our project and added it to source control. Any approach is good, we only need to be able to run it in the root directory of our project in one way or another.

Now let's get into the root directory of our project and create a couple of directories:

  mkdir painter
mkdir generated

We are almost ready to try out things. First, though, we need a template to generate from.

Let's add a new file to the folder painter named Enum + Count.stencil . Then we write our first code:

  {%    for    enum    in    types .   enums  %  } 
  extension    {{19659041] enum    name  .}}    {
    static       count :    int    {   return    {{19659041] enum .   cases .   count  }}  } 
} 
 {%    EndFor  % } 
 }}  & # 39; s ,  {%  & # 39; s and %}  is Stencil 

Stencil deserves a full Bite of its own but for now we only need to know that statements within these codes are evaluated by sourcery command line tool, and iterated or replaced when generating Swift code.

The rest of the content is common Swift code.

Everyone who has worked on a web app in recent years should feel right at home with this technique. Instead of generating HTML, we understand Swift code, pretty!

Let's down what happens in our template:

First, we will repeat through all enums [19659040] 19659040] for enum in {% EndFor % }

Then we find for each enum that we will expand it to have a new static property called count . ].

Static var count : Int { return {{ enum . cases . count }} }
}

This property will return the number of cases in enum . (Gives us some functionality that currently lacks from Swift itself).

Finally, we can drive sourcery .

  ./ sourcery. painter generated - watch

We've gone to the flag - see to make sourcery view our malfires and restore them any time it sees a change. Tidy.

This will scan the source code a bit, and then create a new file in the generated directory called Enum + Count.generated.swift . [19659000] It will look like this:

  extension    SpaceshipKind    {
    static    var    count :    Int    {   return [19659012]   ] 
} 

extension CrewRank { static var count : Int { ] extension HTTP Method count count ]. Int [19659049] { return 7 } }

How cool is that?

Now we only have to add this generated file to our Xcode project as we would have another file. The content will be replaced at any time sourcery is running. Pro Tip: We may also add a new "Run Script ..." Build phase for our Xcode project to run sourcery command (without - see of course) at the beginning of every building of our app. Very fun.

Sourcery Github repo offers some very useful example templates to add things like Equatable and Hashable. These examples are a great way to learn more about what is possible.

Of course, we have barely scratched the surface of what is possible with Sourcery. Watch out for future bits where we will explore much more ...

Learn more and find full documentation of Sourcery at git.io/sourcery


Source link