-
Notifications
You must be signed in to change notification settings - Fork 5
SwiftScripts
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.
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.
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.
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.
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.swiftThis is the approach that more traditional scripting languages take.
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).
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.
$ swiftargument.swift "The quick brown fox"
0 - ./argument.swift
1 - The quick brown fox
$ swift argument.swift The quick brown fox
0 - ./argument.swift
1 - The
2 - quick
3 - brown
4 - fox
$ 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
$ swift argument.swift The\ quick\ brown\ fox
0 - ./argument.swift
1 - The quick brown fox
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!
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.
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.
// ...
}
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
Below is an index of all the example scripts, in order, along with a brief description describing each.
- Hello, World!
The simplest shell script in Swift. - Print Arguments
A simple shell script that indexes & prints the user's input. - Hello, (Somebody)!
The simplest shell script in Swift that accepts user input.
-
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). -
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