Life is Rich All the time.

Swift and the Command Line

Written by Rich Wardwell on 08 Jun 2014.

One of the first things that intrigued me with the ease of writing code interactively in the Xcode Playground was the feasibility of using Swift as a possible replacement or supplement to traditional shell scripts. When Chris Lattner (one of the founders of the language at Apple) posted the following on Twitter, I knew I was on to something:

Of course Swift supports #! scripts, you can immediately execute a Swift script with "xcrun Swift -i".

Why would you want to do this? Well, first, Swift is quite easy to build fully functional apps very quickly and efficiently, all while maintaining the full power of Foundation. Swift discards the old syntactical chrome of Objective-C (or more accurately C), particularly the whole requiring of a main() method as an entry point to your program. Combined with the ability to actually run an uncompiled Swift file directly from the command line dramatically reduces the friction of using a complete, powerful, system-level language where only simple, barebones scripts would operate before. Swift can bridge the gap between traditional shell scripts and full blown applications.

One of the first things I started tinkering around with when I got home was making this a reality. It's actually not quite as simple as the tweet, but it definitely is quite doable, and opens up a whole new realm of possible opportunities from the command line. So, let's make this happen.

The first step is ensuring that you have the appropriate Xcode selected. From the terminal, you can determine your currently selected Xcode:

xcode-select --print-path

You are likely still pointed to the original Xcode 5 install that does not include Swift. Unless the response looks something like this: /Applications/, you need to switch over to the new beta:

sudo xcode-select --switch /Applications/

The location above presumes you placed the Xcode 6 Beta in your applications folder. If you chose somewhere else or renamed the app, you'll need to modify accordingly.

At this point, you can actually run a Swift file directly from the command line. We'll show that as well, but we really want to run our file without having to actually type out the xcrun command. Let's go ahead and create a simple Swift application. Open up your favorite editor and create a Swift file (e.g. HelloWorld.swift) with the following first line hashbang to instruct the shell on how to handle what follows:

#!/usr/bin/xcrun swift -i

println("Hello World!")

Don't forget to modify the permissions of your newly created shell script. By default, the script will not be marked as executable. A simple call to chmod will fix this:

chmod +rx  # adds read and execute for everyone

or my preferred syntax:

chmod 755  # read/write/execute for owner and read and execute for everyone else

While you could now type the following from the command line to run your program:

/usr/bin/xcrun swift -i HelloWorld.swift

...there is a much simpler way. Due to the hashbang line at the top, you should be able to just type HelloWorld.swift (or ./HelloWorld.swift depending on how your path environment variable is setup) and see the traditional welcoming first words of application life.

Without the traditional main method, you don't have apparent access to the command line arguments. These are made available through the C_ARGC and C_ARGV constants. You can iterate over C_ARGV or address specific arguments directly much like a traditional Swift array.

While this is exciting, we still have one small hurdle. If you attempt to import Foundation, allowing access to the file system or environmental variables or a whole slew of other functionality, you'll receive an odd error. We need to let xcrun know where the SDK resides. If you run your Swift file manually, you can use the following:

/usr/bin/xcrun swift -i -sdk $(xcrun --show-sdk-path --sdk macosx)

Unfortunately, it doesn't appear that the substitution works appropriately when used in the hashbang portion of a shell script. I was forced to paste the results from the 2nd xcrun manually. There may be a better way that I'm unware of — until then, replace the first line of your script with the following:

#!/usr/bin/xcrun swift -i -sdk /Applications/

Now you can access all the goodies Apple provides with a simple import, allowing you to do something like the following:

import Foundation

let user = NSProcessInfo.processInfo().environment.objectForKey("USER") as String
println("Hello World, this is \(user.uppercaseString)")

let currentPath = NSFileManager.defaultManager().currentDirectoryPath
println("The current directory is \(currentPath)")

let contentsAtPath = NSFileManager.defaultManager().contentsOfDirectoryAtPath(currentPath, error: nil) as String[]
for contentItem in contentsAtPath

Obviously, this doesn't really do much useful, but it hopefully triggers some ideas and possibility of the many things you could do. With a small framework to simplify some of the traditional functionality often used within command line shell scripts, Swift could quickly become the go-to tool for developing everything from simple scripts to full blown command-line apps. Go forth and code!

WWDC 2014 - Keyword: Mindblowing

Written by Rich Wardwell on 07 Jun 2014.

After returning home from a mind-blowing week of WWDC goodness, I’m still trying to wrap my mind around the happenings of the last 5 days. Now begins the race to watch the plethora of videos of unattended sessions, plowing through Apple’s Swift book, and tinkering with my personal projects as guinea pigs for all the new toys uncovered.

The legion of new SDKs and updates and additions to existing SDKs are absolutely astounding. That was all before they dropped the bombshell of Swift. If the keynote had ended right before the Swift announcement, I would have been completely satisfied and pleased with the announcements made. The Swift unveiling was flooring - how did they keep this under wraps? No one was expecting this.

Some gnashing of teeth could be heard for the first couple days after the announcement, but by the end of the conference, the general vibe seemed to be very positive. The more I came to know about the new language, the more impressed I became. It truly is the future of Mac and iOS development (and not only because Apple has all but mandated it to be so).

Capture My(self)

Written by Rich Wardwell on 04 Mar 2014.

One of the wonderful elements of my job at Black Pixel is participating in the blog there. The following is a snippet from my recent article on capturing self within blocks.

Occasionally in my software development career, some code or comment will trigger a bolt of fear through my psyche. Were my assumptions incorrect? Have I been doing this wrong all along? Did I ever really understand why I was doing this in the first place? Usually, the response includes stepping back, reassessing with a scientific analysis of the situation, writing some test code, and then reconfirmation (or readjustment) of my assumptions.

Recently, while reviewing some technical reviews of a chapter in a book I’m coauthoring, that familiar pang of fear echoed once again through my consciousness. The target of this loss of faith and understanding revolved around my assumptions and understanding of retain cycles, blocks, and capturing of `self`. As in the past, it was time to solidify and reaffirm the foundation of understanding.

For more, see the full article at the Black Pixel Blog.