Swift 4, Review the New - Part One

20 October, 2017

AleksandrPavliuk

On September 19, 2017, Apple announced release of Swift 4.0 on the official blog of Swift language. Great news is that new Swift doesn’t contain so many epic changes like Swift 3.0 did, and most changes have full backwards compatibility. So you can just relax and kick back, let’s take a quick look at all innovations.

1. One-Sided Ranges

RangeExpression protocol was added to simplify creation of methods that use ranges. Also the standard library can detect start and end indices of ranges from now, so you don’t need to explicitly specify them [SE-0172]:

let s = "Hello, World!"

let i = s.index(of: ",")!

// half-open right-handed range

let greeting = s[..<i]

// closed right-handed range

let withComma = s[...i]

// left-handed range (no need for half-open variant)

let location = s[i...]]

A great way to use one-sided ranges is pattern matching:

switchyear {

case2001...: print("Next millennium is here")

default: print("Keep calm and wait!")

}

2. Strings and chars updates

Multi-line String Literals

The multi-line string literals come in handy when you need to build long formatted texts for UI or XML or JSON messages. In Swift 4, you can do this using three double-quotes (""") [SE-0168]:

let longAndFormatedString = """

“Talk is cheap. Show me the code.”

― Linus Torvalds

"""

“Talk is cheap. Show me the code.”

― Linus Torvalds

You don't have to avoid quotes in here, very useful.

String Newline Escaping

Another capability that was added in Swift 4.0 is simple, but helpful - preventing line breaking by adding (\) [SE-0182]

letescapeNewLine ="""

“Talk is cheap. Show me the code.” \

― Linus Torvalds

"""

“Talk is cheap. Show me the code.” ― Linus Torvalds

String is a Collection... again

Strings are collections like they were before Swift 2.0. This change allows us to skip characters array usage during iteration, you can do it directly over String.

let iterateMe = "Please"

for char initerateMe {

print(char)

}

String, Substring, and StringProtocol

To improve operation of string slices, they become instances of Substring and conform to new protocol StringProtocol as well as String.

Developers need to keep in mind that a Substring keeps the full String value it was created from alive. This can lead to incorrect memory usage. To prevent such situations, it is recommended that most functions, which take strings as arguments, continue accepting only String instances.

You generally should not make such functions generic to accept any value conforming to StringProtocol. To convert Substring into String, use String initializer:

let newString = String(substring)

Unicode 9

Swift 3 doesn’t determine the number of unicode characters made up of multiple code points correctly. This issue is fixed in Swift 4.

"".count// person + skin tone; in Swift 3: 2

"".count// person + skin tone + profession; in Swift 3: 3

"".count// multiple flags; in Swift 3: 1

The unicodeScalars Property Added to Character

Swift 4 adds the unicodeScalars property to characters, so you can access it directly now [SE-0178]:

let character: Character = "A"

let unicodeScalars = character.unicodeScalars

3. Private Access Modifier for extensions

Swift 4 realizes the original intent by sharing the same access control scope between a type and any extension of said type. This only holds true within the same source file [SE-0169]:

struct StructWithPrivateFoo {

private var foo: Int = 0

}

extensionStructWithPrivateFoo {

mutating func modifyFooWith(i: Int) {

// foo is visible here

foo = i

}

}

4. Smart KeyPaths

Unlike the string-based key paths in Cocoa, Swift key paths are strongly typed. Now to create a key path, you simply use a back-slash followed by the property you're interested in:

struct User {

let name: String

}

let user = User(name: "Vasil")

let keyPath = \User.name

let userName = user[keyPath: keyPath]

Key paths are objects that can be stored and manipulated.

5. Encoding & Decoding

Archival and Serialization

Earlier, to serialize and archive your custom types, you had to do extra work: for classes you had to subclass NSObject and implement the NSCoding protocol, for value types you had to do even more work. In Swift 4, this problem is solved by adding the Codable protocol [SE-0166]:

struct Video: Codable {

enum Kind: Int, Codable {

case Unknown, Static, Live

}

let kind: Kind

let isPlaying: Bool

let isBuffering: Bool

}

let video = Video(kind: .Static, isPlaying: true, isBuffering: false)

Encoding

Once you have a Codable value, you need to pass it to an encoder in order to archive it. Swift 4 comes with a built-in set of encoders and decoders for JSON (JSONEncoder and JSONDecoder) and property lists (PropertyListEncoder and PropertyListDecoder). These are defined in [SE-0167]:

var encoder = JSONEncoder()

let jsonData = tryencoder.encode(video)

let jsonString = String(data: jsonData, encoding: .utf8)

// {"kind":1,"isBuffering":false,"isPlaying":true}

Decoding

Decoding is pretty similar:

let decoder = JSONDecoder()

let decodedVideo = trydecoder.decode([Video].self, from: jsonData)

There are more changes presented by Swift 4, including updates to Dictionary and Set, improved integers, generic subscripts, and more. Read about about them in Swift 4, Review the New - Part Two. Stay tuned!

Thank you for reaching out to Sigma Software! Please fill the form below. Our team will contact you shortly.

Full Name *

E-mail *

Phone

Company

Message

Page url

I hereby confirm that I am familiar with
Sigma Privacy Policy and agree to the personal data provided by me being stored and processed in accordance with the Policy
*

Aleksandr

Pavliuk

iOS Developer

Aleksandr is an experienced iOS Developer and an enthusiast of Swift. He has solid understanding of the mobile development process and tunes into emerging technologies, trends, and events in the field.