Andrew Fitzpatrick
In last week’s WWDC, Apple introduced an entirely new language for Mac and iOS development called Swift. Swift is a modern language that is less verbose but is just as expressive as Objective-C. Furthermore, Swift offers a number of features not available in Objective-C. We at the Big Nerd Ranch are incredibly excited about it.
And while the news of this new language is exciting, it’s also intimidating. The introduction of Swift means that many hours of work lay ahead. This realization may inspire some anxiety for developers, but don’t fear! It’s important to know that Objective-C isn’t going anywhere in the near term. From working with legacy code and Apple’s Foundation frameworks to understanding prominent development patterns in Mac and iOS, it still makes sense to be comfortable with Objective-C. Developers will be encountering Objective-C in their daily work for some time to come. To be sure, many of the lessons, tricks and best-practices are still relevant.
Moreover, apps won’t be able to ship to the App Store with Swift until iOS 8 is released later this fall. That means you have some time to get familiar with Swift. For now, your daily development will proceed as it has for the past few years. If you’re working on a project that won’t release prior to iOS 8, then go ahead and start incorporating Swift into your app. If that isn’t your case, then go ahead and start playing! In the meantime, there’s a lot to learn and a lot to be excited about. Here are some of our favorites.
Apple has made the process of integrating Swift with Objective-C relatively straightforward. The beauty of Apple’s integration of the two languages is that any Objective-C framework or C library that is available as a module can be imported directly into Swift like so:
import Foundation. After this import, all of the Objective-C Foundation classes that you have been using for the past several years are now available in your Swift file as Swift APIs. For example, a method in Objective-C that takes a
NSString instance as an argument will be converted to take a
String in Swift.
Apple describes Swift as a type safe language. Swift performs type checks as it compiles our code, and will refuse to build if any lines have mismatched types. Accordingly, we have strong protections against accidentally assigning an
Int to a
String.
And while this type safety is helpful, the magic really happens in Swift’s type inference capabilities. In other words, you don’t have to declare the type for every constant or variable. For example, if you type:
let names = ["Aaron", "John", "Matt"], then Swift knows that this instance called
names is an
Array that contains instances of the
String class.
We can send messages to nil in Objective-C, and while that can prevent us from crashing awkwardly, it can also lead to painful time spent figuring out why an object has somehow become unexpectedly nil. In Swift, by default, instances are not allowed to be nil at all. Nonetheless, we can still use the expressive power of messaging nil (and getting nil back) when we want it by using Optionals. Optional Chaining in Swift makes it clear you are sending messages to an instance that might be nil, and you’re aware that you might get nil back. For example, imagine that
myCollectionOfMinis was declared as follows:
var myCollectionOfMinis: Array?. The
? means that
myCollectionOfMinis can optionally be nil. We can then use Optional Chaining to access the array’s count should it contain any instances.
if let myMiniCollectionCount = myCollectionOfMinis?.count { println("\(myMiniCollectionCount) is a lot of minis!") } else { println("You better get on it!") }
Swift is a much more functional programming language than Objective-C. For example, consider again our variable above representing a collection of cool minis. Let’s say we want to grab minis from this array that pass a certain condition. We can accomplish this operation in Swift by using the
filter function. For example:
let paintedMinis = myCollectionsOfMinis.filter { (coolMini) -> Bool in return coolMini.isPainted }
The example above filters from the general collection all minis that are not painted. Let’s compare that to how we’d accomplish the same task in Objective-C:
NSMutableArray *paintedMinis = [NSMutableArray array]; for (CoolMini *mini in myCollectionOfMinis) { if (mini.isPainted) { [paintedMinis addObject:mini]; } }
As we can see, the execution of this task in Swift is more elegant and feels far less mechanical.
Unlike C and Objective-C, Swift structures can have initializers that prepare instances for use. Consider the following example:
struct Nerd { var hasGlasses: Bool var favoriteLanguage: String init (hasGlasses: Bool, favoriteLanguage: String) { self.hasGlasses = hasGlasses self.favoriteLanguage = favoriteLanguage } } var bigNerd = Nerd(hasGlasses: true, favoriteLanguage: "Swift")
The above shows that the difference between structures and classes is lessened in Swift. Oh, and did we mention that structures can define methods now as well? Two major outstanding differences are that structures lack inheritance and deinitializers. Nonetheless, structures have been significantly upgraded.
The items mentioned above are just a small collection of the awesome features introduced in Swift. For example, we didn’t cover the power and flexibility brought to us by Generics. Given that there is so much to explore, the question becomes: what should I do to prepare for Swift and iOS 8? Here are some tips:
Finally, there couldn’t be a better time to get started with, or return to, developing Mac and iOS apps. The introduction of a new language means that the playing field has been leveled to a significant degree. If you’re a venerable Objective-C programmer, then this doesn’t mean your knowledge is obsolete. Your experience will still serve you well. In either case, we believe Apple has provided the Mac and iOS development community (both the present and prospective) with an exciting, powerful language that will make development more pleasurable and