What’s New in Swift 3?

Datetime:2016-08-23 04:14:27          Topic: Swift           Share

It’s a well-known fact that the software development industry moves rapidly, with the latest new framework, SDK or paradigm changing every so often. The one thing you hope will remain constant through all this is your programming language – the foundation upon which we build our empires. Unfortunately, this hasn’t been entirely true if you decided to pick up Apple’s new programming language – Swift.

Swift was released in June 2014, and here we are about to explore version 3.0. In contrast, Python was released in 1991 and hit version 3.5 in June 2016. The rapid changes in Swift have meant refactoring our code base all too often and getting used to subtly different inner workings.

Unlike the transition from Swift 1 to 2, the transition from 2.x to 3.0 is much gentler in some ways. This is largely due to the open sourcing of Swift late last year, which meant that any changes to Swift and surrounding discussion happened “gradually” and out in the open, rather than the usual fall release of everything Apple related. At the same time, for those of us who use Swift for iOS development, some of the changes mean migrating our codebases won’t be easy.

There are several changes to the language, some major, some minor and in this post, we’re going to look at some of the important changes, at a high level. In subsequent posts, we’ll dive into the details of some of the larger ones.

Since Swift is now developed in the open, you can take a look at the evolution page to track changes to the language. The page links to every single proposal implemented along with a definition of the problem, the proposed solution, any alternatives considered and the impact on existing code. It really is quite well done.

Start learning to code today with a free trial on Treehouse.  

Major Proposals

A bit of context before we dive in. The proposals listed in this section are those I consider “major” from a perspective of a fairly new/inexperienced developer. There are proposals that have been accepted and implemented in Swift 3 that are quite important to developers (like Enhanced Floating Point Protocols ) that have been omitted from this list. If you are fairly comfortable with Swift and want to the nitty gritty about what’s coming up in version 3.0, I suggest going straight to the Swift evolution page.

API Design Guidelines

When you open up a Swift 2 project and migrate to Swift 3, the most obvious change you will encounter is the new API design guidelines. This proposal is part of three related proposals:

The API Design guidelines proposals aims to codify Swift’s design guidelines moving forward. While Swift 2 and prior did follow a set of conventions, because of the early release and rapid iteration of the language, much of the standard library and APIs were named haphazardly. Swift 3 rewrites these conventions and makes them very clear.

We won’t go over every single detail in this post but here’s the gist of things:

  • When writing Swift 3 code, your naming conventions should promote clear usage. This includes avoiding ambiguous and needless words, relying on type information to provide meaning and focusing on clarity over brevity.
  • Parameter names and argument label rules have changed. Swift 3 makes all argument labels the norm, including the first (which was automatically eliminated at the call site in Swift 1 and 2). Furthermore, specific rules around how a method should be named are included, depending on whether the argument forms a prepositional phrase or a grammatical phrase.

These new rules have been applied to the standard library as well which means that common function and method names are different. For example sort() has become sorted() , reverse() -> reversed() and so on.

There are several rules and explaining it with a one liner doesn’t do the proposal justice so we’ll go over the logic behind these naming choices in a separate, future post. For now, you should go look at a summary of the rules on the Swift page itself.

The next major component of this overarching change is that Objective-C APIs translate into more “Swifty” code. Here’s a simple example right from the proposal. This is what an Objective-C API imported into Swift 2 looked like:

let content = listItemView.text.stringByTrimmingCharactersInSet(NSCharacterSet.whitespaceAndNewlineCharacterSet())

Here is the same API in Swift 3:

let content = listItemView.text.trimming(.whitespaceAndNewlines)

Notice that stringByTrimmingCharactersInSet is now imported as trimming and NSCharacterSet.whitespaceAndNewlineCharacterSet() which is a class method on NSCharacterSet, is now an enum case, .whitespaceAndNewlines , on the CharacterSet type.

These changes indicate the usage of more Swift types (enums) along with the goal of relying on type information to provide meaning. Since the method takes a value of type CharacterSet , the method name does not have to include “charactersInSet”. Swift 3 considers this redundant type information.

These aren’t trivial changes. The change in translation of Objective-C APIs along with the change to Foundation types (detailed below) means that much of our code will look different. It will take some time getting used to.

Foundation Types

From the outset, Swift has worked well with Objective-C. Since Objective-C carries with it a rich history and decades of work, it didn’t make much sense to reinvent the wheel. This is evident in Swift’s use of Objective-C’s Foundation types to provide much needed functionality.

Foundation types don’t gel well with Swift’s goal of “mutability when you need it” however and in Swift 3, we have an entirely new set of Foundation value types that correspond to the reference types in Objective-C.

We’ve always had a String value type to correspond to NSString, Array for NSArray and so on, but Swift 3 takes this goal much further. NSURL is now URL, NSDate is Date, NSCharacterSet is CharacterSet, etc.

These types have the same functionality as their reference types but the API is now more Swifty and encapsulated in a value type. This means that constant values now remain immutable and that API follows the new design guidelines. Consider the following example:

Swift 2:

let date = NSDate()
date.dateByAddingTimeInterval(1000) 

In the example above the fact that we created date as a constant doesn’t really mean anything. Mutability is guaranteed by the class rather than whether it’s a constant or a variable. Furthermore, the method name has to be designed in such a way as to indicate mutability semantics. In this case, we know that we aren’t mutating the date instance because the method name indicates that we get a new date back.

This type of method name also doesn’t fit well with Swift 3’s API design guidelines.

Using the new Date type in Swift 3 however, the semantics are much clearer. Since it is a value type, declaring with let vs. var makes a big difference.

Swift 3:

let date = Date()
date.addTimeInterval(1000) // Error: 'date' is a let constant

In this case, we’ve declared the date instance as a constant. When we try to add a time interval we get an error. The method is mutating so to make this work we need to have a variable instance.

Several Foundation types have Swift equivalents now, which means that we’ll need to retrain our brains to use the new value types as well as figure out how the API has been translated over.

Modernized libdispatch

Grand Central Dispatch, or libdispatch as the C library is known, is the mechanism by which concurrency support is provided across Apple platforms. In Swift 2.x, libdispatch is imported almost verbatim from C which leads to some not so elegant code. Here’s an example:

let queue = dispatch_queue_create("com.test.myqueue", nil)
dispatch_async(queue) {
    print("Hello World")
}

In Swift 3 the API is much improved to include a new type with convenience methods. The same example in Swift 3:

let queue = DispatchQueue(label: "com.test.myqueue")
queue.asynchronously {
    print("Hello World")
}

This is a significant improvement over the previous API!

Swift Package Manager

Swift 3 includes a tool, the Swift Package Manager, for managing the distribution of Swift code. It’s integrated with the Swift build system to automate the process of downloading, compiling, and linking dependencies.

It’s taken a while but it looks like we’re finally getting an Apple sanctioned package manager. No more CocoaPods vs Carthage flame wars :wink:

Minor proposals

Those are some of the big proposals that will affect Swift developers up front, but this is a big release and there are lots of smaller changes that will affect our code.

Modified Enum syntax

There are two proposals here to be aware of:

With Swift 3, non-type declarations are all lowercase. This means that enum members now follow lowerCamelCase conventions. This is pretty easy to understand. The following code in Swift 2:

enum Rank {
    case Ace
    case Two, Three, Four, Five, Six, Seven, Eight, Nine, Ten
    case Jack, Queen, King
}

Now looks like this in Swift 3

enum Rank {
    case ace
    case two, three, four, five, six, seven, eight, nine, ten
    case jack, queen, king
}

While it might be weird at first sight (I’m still not used to it), it does make evident that only types are UpperCamelCase in code. No room for ambiguity.

The second related change is that for enum instance member implementations, the leading dot is mandated. This is better understood with an example.

Here’s a bit of Swift 2 code:

enum Week {
  case Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday

  func isWeekend() -> Bool {
    switch self {
      case Saturday, Sunday: return true
      default: return false
    }
  }
}

Note that in the switch statement, where we reference the instance members, the leading dot is not required. However in Swift 3, The same code would be as follows with a mandated leading dot:

enum Week {
  case sunday, monday, tuesday, wednesday, thursday, friday, saturday

  func isWeekend() -> Bool {
    switch self {
      case .saturday, .sunday: return true
      default: return false
    }
  }
}

Lots more

Other minor changes include:

  • ErrorType is now ErrorProtocol to better reflect new naming guidelines
  • Swift 3 includes a new set of access level modifiers like fileprivate with changes in the behavior of existing modifiers
  • C style for loops and incrementing operators (++ and –) have been removed from the language

Needless to say, the transition to Swift 3 is a big one. We’ve only just scratched the surface of all the changes in the new release. I highly recommend you check out the Swift evolution page and do a bit of reading to get up to speed!

New to Swift? Tune in next month for the release ofPasan‘s newest course: Swift 3 Basicsto learn how to program from absolute scratch using Swift 3 and learn  fundamental concepts that will get you started writing code immediately. 

If you’re ready to start your career as an iOS developer, enroll in the iOS Development Techdegree and start your free trial today.





About List