Skip to content

SwiftScripts

Blake Merryman edited this page Aug 30, 2015 · 2 revisions

Swift Scripts

Blake Merryman

This is a brief introduction to using Apple's new Swift programming language for scripting.

All examples were developed with and assume OS X Yosemite (v10.10.1) and have Xcode 6.1.1 set as the default development environment. See Developer Setup for assistance if your setup does not match.

Tools Needed:

  • Properly configured Mac for Development
  • A Trusty Text Editor
  • The Terminal

Please note that no IDEs were hurt in the making of this introduction.


Sections


Up and Running in 3 Steps

Suppose we already have a simple Swift program, HelloWorld.swift, that we want to run from the command line:

println("Hello, World!")

We can turn this into a script in 3 simple steps.

1. Shebang

The magic behind creating a Swift script is a single line of code:

#!/usr/bin/env xcrun swift

Adding this line to the very top of your program is what makes everything work.

2. Make Executable

After we have completed (or edited) a script, we can make a script executable with the following command:

$ chmod +x HelloWorld.swift

Note:
chmod +x doesn't truly compile a binary in the traditional sense (i.e. creating a seperate, executable binary). It changes the file's permission to be executable (hence the +x). This is all that most simple Swift scripts will need. For more advanced compilation, see the Compiler section of Advanded Topics.

3. Run

Now you will be able to call your script from the terminal:

$ ./HelloWorld.swift

Note:
You can skip the compile phase and run your script inline from the terminal like so:

$ swift HelloWorld.swift

This is the approach that more traditional scripting languages take.


Accepting Arguments

Feeling Argumentative

A simple, output-only script is neat but a truly interesting (read: useful) script acts on our input. We don't have to do anything additional to get our program to accept input from the Terminal. We simply have to handle it correctly in the program itself.

All user input is retrieved from Process.arguments as an array of strings. The first argument in the array is the path to our program. Everything after that is user input from the terminal. All received arguments are space-seperated values (unless grouped by quotes or escaped).

Example 1:

Consider the following program, PrintArguments.swift:

#!/usr/bin/env xcrun swift

for (index, argument) in enumerate(Process.arguments) {
    println("\(index) - \(argument)")
}

// enumerate(...) allows indexing within a for..in.. loop.
// The tuple at the beginning contains the index & corresponding argument.

1st Run - With Quotes:

$ swiftargument.swift "The quick brown fox"

0 - ./argument.swift
1 - The quick brown fox

2nd Run - Without Quotes:

$ swift argument.swift The quick brown fox

0 - ./argument.swift
1 - The  
2 - quick  
3 - brown  
4 - fox  

3rd Run - Mixed Input (With & Without quotes):

$ swift argument.swift The quick brown fox "jumped over the lazy dog"

0 - ./argument.swift  
1 - The
2 - quick  
3 - brown  
4 - fox  
5 - jumped over the lazy dog  

4th Run - Escaped Spaces

$ swift argument.swift The\ quick\ brown\ fox

0 - ./argument.swift
1 - The quick brown fox

Example 2:

Now let's go back to our simple HelloWorld.swift program. To add user input, we simply have to handle user input correctly and pull out the appropriate argument(s):

#!/usr/bin/env xcrun swift

println("Hello, \(Process.arguments[1])!")

// We are only interested in the first user-supplied argument.
// The zeroth element is "./2-Hello.swift" (the path to our script).

In the terminal:

$ swift HelloSomebody.swift "Blake Merryman"

Hello, Blake Merryman!

Advanced Topics

Compiling as a Binary

There are several instances where you may need to actually compile your Swift scripts (e.g. desire a binary format to distribute or need more advanced compilation options for a larger project).

Once we have our environment set up properly, let's check on our Swift compiler. Run this command in the terminal:

$ xcrun -f swiftc

You should get something like

/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swiftc

If you are on OS X Yosemite and running Xcode 6.1, no further action is required; you can access the compiler with swiftc in the terminal.

Otherwise, I would suggest adding an alias to our bash profile for convenience.

alias swiftc=/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swiftc

To compile a Swift file:

$ swiftc HelloWorld.swift

This creates a binary of the same name, HelloWorld, in the source directory.

Handling User Input

Checking for user input from the console is easy:

let userInput = Process.arguments

if userInput.count > 1 {

    // Do something with userInput
    // ...

} else {

    // No arguments received (other than the path to our script).
    // Handle this appropriately.
    // ...
}

Importing Existing Frameworks

If you need a little more power in your script or you want to leverage some existing code, you can import other frameworks to help out. All the Apple Frameworks are simple, just add import <AppleFrameworkName> near the top of your file. Importing third party frameworks

  • Argument flags...
  • Adding a script to your path
  • Linking multiple files into one program
  • Importing frameworks

Index of Scripts

Below is an index of all the example scripts, in order, along with a brief description describing each.

  1. Hello, World!
    The simplest shell script in Swift.
  2. Print Arguments
    A simple shell script that indexes & prints the user's input.
  3. Hello, (Somebody)!
    The simplest shell script in Swift that accepts user input.

Developer Setup

  1. Check OS X and Xcode

    All examples and steps in this guide were developed on a Mac running OS X Yosemite (v10.10.1) with Xcode 6.1.1 (build b6A2008a) installed and active. If you have this set-up, move on to step 2. Otherwise, additional setup is required.

    To check which version of Xcode is running on your system, enter the following command into your terminal:

    $ /usr/bin/xcodebuild -version

    which should return something like:

    Xcode 6.1.1
    Build version 6A2008a

    NOTE:
    If you need to switch your active version of Xcode, run the following terminal command:
    $ sudo xcode-select -switch /PATH/TO/.../Xcode.app/Contents/Developer
    where /PATH/TO/.../Xcode.app is the path to Xcode 6.1.1 (followed by /Contents/Developer).

  2. Swift Compiler

    Swift scripts only need to be compiled using the Swift Compiler if a binary format is desired or needed. Otherwise, compiling simple scripts is accomplished by changing the file permissions with chmod +x to allow execution. See Advanded Topics for advanced compilation.

    Once we have our environment set up properly, we also need to check on our Swift compiler. Run this command in the terminal:

    $ xcrun -f swiftc

    You should get something like

    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swiftc

    If you are on OS X Yosemite and running Xcode 6.1, no further action is required; you can access the compiler with swiftc in the terminal.

    Otherwise, I would suggest adding an alias to our bash profile for convenience.

    alias swiftc=/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swiftc

References