What’s New in Swift 5?
Swift 5 is finally available in Xcode 10.2! This release brings ABI stability and improves the language with some long-awaited features. See what’s new! By Cosmin Pupăză.
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Contents
What’s New in Swift 5?
25 mins
- Getting Started
- Language Improvements
- Testing Integer Multiples
- Escaping Raw Strings
- Using New Character Properties
- Using New Unicode Scalar Properties
- Removing Subsequences
- Dictionary Updates
- Compacting Dictionaries
- Renaming Dictionary Literals
- Numeric Protocol Updates
- String Interpolation Updates
- Handling Future Enumeration Cases
- Adding Result to the Standard Library
- Conforming Never to Equatable and Hashable
- Dynamically Callable Types
- Swift Package Manager Updates
- Platform Deployment Settings
- Target Build Settings
- Dependency Mirroring
- Miscellaneous Bits and Pieces
- Making Codable Ranges
- Flattening Nested Optionals
- Removing Customization Points From Collections
- Identity Key Paths
- Initializing Literals Through Coercion
- Build Configuration Updates
- Using Variadic Parameters for Enumeration Cases With Associated Values
- Deprecating String Index Encoded Offsets
- New Pointer Methods
- SIMD Vector Updates
- Where to Go From Here?
Great news! Swift 5 is finally available in Xcode 10.2! This release brings ABI stability and improves the language with some long-awaited features.
In this tutorial, you’ll learn about the most important changes in Swift 5. Swift 5 requires Xcode 10.2, so make sure to install it before getting started.
Getting Started
Swift 5 is source compatible with Swift 4.2, but isn’t binary compatible with earlier Swift releases. However, future releases will be binary compatible with Swift 5 thanks to ABI stability.
ABI stability enables binary compatibility between apps and libraries compiled with different Swift versions. The Swift standard library and runtime get embedded in the OS, so apps don’t distribute their own copy of the libraries on any platform. This leads to better tool decoupling and OS integration.
You also need ABI stability to distribute binary frameworks that work across multiple Swift versions. This requires module format stability, which stabilizes the module file containing the compiler’s representation of the framework’s public interfaces.
You’ll find Swift Evolution proposal numbers like [SE-0001] in each section of the tutorial. You can learn more about each new change by exploring each proposal link.
The best way to follow this tutorial is to try out the new features in a playground.
Fire up Xcode 10.2 and select File ▸ New ▸ Playground. Set the platform to iOS and the template to Blank. Name and save it anywhere you want. Time to get started!
Language Improvements
There are many language features in Swift 5, such as dynamic callable types, handling future enumeration and more.
Testing Integer Multiples
In Swift 4.2, you determine whether a number is a multiple of another with the remainder operator:
let firstNumber = 4
let secondNumber = 2
if secondNumber != 0 && firstNumber % secondNumber == 0 {
print("\(secondNumber) * \(firstNumber / secondNumber) = \(firstNumber)")
}
How this code works:
- Check that
secondNumber
isn’t 0. - Check that dividing
firstNumber
bysecondNumber
returns a remainder of 0. - Perform the divide operation.
You must check that secondNumber
isn’t 0
, because %
throws an error if it is.
Swift 5 simplifies this by adding isMultiple(of:)
to BinaryInteger
[SE-0225]:
if firstNumber.isMultiple(of: secondNumber) {
print("\(secondNumber) * \(firstNumber / secondNumber) = \(firstNumber)")
}
isMultiple(of:)
works even if you pass it an argument of 0, and the resulting code is much cleaner.
Escaping Raw Strings
Swift 4.2 uses escape sequences to represent backslashes and quote marks in strings:
let escape = "You use escape sequences for \"quotes\"\\\"backslashes\" in Swift 4.2."
let multiline = """
You use escape sequences for \"\"\"quotes\"\"\"\\\"\"\"backslashes\"\"\"
on multiple lines
in Swift 4.2.
"""
Swift 5 adds raw strings. You add #
at the beginning and end of the string so you can use backslashes and quote marks without issue. [SE-0200]:
let raw = #"You can create "raw"\"plain" strings in Swift 5."#
let multiline = #"""
You can create """raw"""\"""plain""" strings
on multiple lines
in Swift 5.
"""#
When using string interpolation in raw strings, you have to use a pound sign after the backslash:
let track = "Nothing Else Matters"
print(#"My favorite tune\song is \#(track)."#)
There are some cases when you need to use more than one #
at the beginning and end of the string:
let hashtag = ##"You can use the Swift "hashtag" #swift in Swift 5."##
In the code above, you add ##
at the beginning and end of hashtag
so that you can represent #
inside the string. The number of #
s used at the beginning of the string must match the number at the end of it.
In Swift 4.2, you escape backslashes inside regular expressions as follows:
// 1
let versions = "3 3.1 4 4.1 4.2 5"
let range = NSRange(versions.startIndex..., in: versions)
// 2
let regex = try! NSRegularExpression(pattern: "\\d\\.\\d")
// 3
let minorVersions = regex.matches(in: versions, range: range)
// 4
minorVersions.forEach { print(versions[Range($0.range, in: versions)!]) }
Here’s how this code works:
- Declare
versions
and define arange
that covers the whole string. - Define a regular expression which matches all minor Swift releases in
versions
. - Determine minor version ranges with
matches(in:options:range:)
. - Use the ranges to get the minor releases from
versions
.
Swift 5 simplifies regular expressions with raw strings:
let regex = try! NSRegularExpression(pattern: #"\d\.\d"#)
In this code, you write regex
using half the number of backslashes, because you don’t need to escape backslashes in raw strings.
Using New Character Properties
Swift 4.2 requires workarounds for common tasks when working with characters:
let id = "ID10"
var digits = 0
id.forEach { digits += Int(String($0)) != nil ? 1 : 0 }
print("Id has \(digits) digits.")
In this code, you determine how many digits id
has by first casting each character to String
, then to Int
.
However, Swift 5 adds properties to Character
which make characters easier to use [SE-0221]:
id.forEach { digits += $0.isNumber ? 1 : 0 }
In this case, you use isNumber
to check if every character is a digit. Have a look at the proposal for other properties you can use.
Using New Unicode Scalar Properties
In Swift 4.2, you implement text processing algorithms for unicode scalars as follows:
let username = "bond007"
var letters = 0
username.unicodeScalars.forEach {
letters += (65...90) ~= $0.value || (97...122) ~= $0.value ? 1 : 0
}
print("Username has \(letters) letters.")
In this code, you compute how many letters username
has by checking if each character’s unicode scalar represents a small letter or a capital one.
Swift 5 adds properties to unicode scalars, which simplify text processing [SE-0211]:
username.unicodeScalars.forEach { letters += $0.properties.isAlphabetic ? 1 : 0 }
In this code, you use isAlphabetic
to check if every character is a digit. The linked proposal shows all the properties you can check.