What’s New in Swift 3?

Check out what’s new in Swift 3 – Swift’s first major release as an open source project. By Ben Morrow.

Leave a rating/review
Save for later

Update 10/3/16: This tutorial has been updated for Xcode 8 and Swift 3.

Swift 3 arrived on September 13, 2016, and brought major code changes to all Swift developers.

If you haven’t been following the Swift Evolution project closely, you may wonder what changes are in store, how it will affect your code, and when you should start porting your code to Swift 3. This article is for you! :]

In this article, I’ll highlight the most significant changes in Swift 3 that will impact your code. Let’s dive in!

Getting Started

Swift 3 is now available in Xcode 8. To allow developers to make the migration to Swift 3 on their own terms, Apple has included Swift 2.3 as a minor update bundled with Xcode 8. To you as a developer, Swift 2.3 is the same as Swift 2.2 but with support for many of the new SDKs and Xcode features announced at WWDC. You can submit to the App Store using Swift 2.3 if you have not yet migrated your code to Swift 3.

I recommend trying out the features we discuss in a playground and maybe even running the Migration Assistant on one of your projects so you can get a feel for everything that is changing.

Migrating to Swift 3

When converting to Swift 3, you’ll notice that practically every file needs changes! That’s largely because, all the Cocoa API names have changed. Or to be more precise, the API is the same, but there’s one name appropriate for Objective-C and one name appropriate for Swift. Swift 3 is going to make Swift much more natural to write in the years ahead.

Apple has included a Migration Assistant with Xcode 8 that can brilliantly make most of these changes in one fell swoop. Don’t be surprised though if you need to touch up a few areas yourself that the migrator doesn’t handle automatically.

You can convert to either Swift 2.3 or Swift 3 immediately. If you ever need to bring it back up, you can always navigate in Xcode to Edit > Convert > To Current Swift Syntax…. The compiler fortunately shares the same smarts as the Migration Assistant as well. If you accidentally use the old API on a method call, the compiler will offer a Fix-It option that will help you use the correct modern API.

Implemented Swift Evolution Proposals

Community members submitted over 100 proposals for changes to Swift since it went open source. A large number of them (70 so far) have been accepted after discussion and modification. Those that have been rejected have sparked some intense discussion as well. In the end however, the core team makes the final decision on all proposals.

The collaboration between the core team and the wider community has been impressive. In fact, Swift has garnered 30 thousand stars on Github. Several new proposals are submitted every week, week-after-week. Even Apple engineers pen proposals on open Github repository when they want to make changes.

In the sections below, you’ll see linked tags such as [SE-0001]. These are Swift Evolution proposal numbers. The links to each proposal have been included so you can discover the full details of each particular change. You can also check the status of all Swift Evolution proposals to see which ones have been implemented. The code examples below build on Paul Hudson’s excellent overview of the common changes you’ll notice in Swift 3.

API Changes

The biggest update in Swift 3 involves the standard library adopting consistent naming conventions across libraries. The API Design Guidleines contain the rules that the team settled on as they were building Swift 3, which place a high value on readability and accessibility to new programmers. The core team operated on the principal that “Good API design always considers the call site”. They strove to bring clarity to the point of use. Without further ado, here are the changes most likely to impact you.

Consistent First Argument Labels

Let’s start off strong with a direct reversal of a practice you use every day in Swift.


The first parameter in functions and methods now always has a label unless you request otherwise. Previously when you called a function or method you omitted the first parameter label [SE-0046]:

// old way, Swift 2, followed by new way, Swift 3

NSJSONSerialization.JSONObjectWithData(data, options: [])
JSONSerialization.jsonObject(with: data, options: [])

addQuadCurveToPoint(endPoint, controlPoint: controlPoint)
addQuadCurve(to: endPoint, controlPoint: controlPoint)

NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask)
FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)

panelView.centerXAnchor.constraint(equalTo: view.centerXAnchor)

array.remove(at: 3)

pngImageData.writeToURL(fileURL, atomically: false)
pngImageData.write(to: fileURL, options: [])

numberOfSections(in: tableView)

SCNAction.moveTo(SCNVector3Make(1, 1, 1), duration: 1)
SCNAction.move(to: SCNVector3(1, 1, 1), duration: 1)

Take note of how the method definitions use prepositions like “of”, “to”, “with”, and ” in” for the external name. These are part of an effort to optimize readability.

If the method call reads well without a preposition and doesn’t need a label, you should explicitly exclude the first parameter name with an underscore:

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { ... }
override func didMoveToView(_ view: SKView) { ... }

In many programming languages, methods may share a base name and offer different parameter names. Swift is no exception, and now you’ll come across overloaded method names much more since the APIs have been translated to be more direct. Here’s an example with two forms of index():

let names = ["Anna", "Barbara"]
if let annaIndex = names.index(of: "Anna") {
  print("Barbara's position: \(names.index(after: annaIndex))")

Altogether, the parameter name changes make method naming more consistent and easier to learn.

Omit Needless Words

In previous iterations of Apple libraries, method names indicated their return value and parameter names included the name of the type they expected. Because of the Swift compiler’s type checking, this is much less necessary. The team took a hard look at how to filter out all the noise so that only the signal remains and thus a lot of word repetition has been removed.


The API has gotten smarter about how Objective-C libraries are transformed into native Swift [SE-0005]:

// old way, Swift 2, followed by new way, Swift 3





animals.insert("Koala", atIndex: 0)
animals.insert("Koala", at: 0)