craiggrummitt
6 min readJun 14, 2018

The latest update of Swift 4.2 came out last week at WWDC, and it has some pretty exciting improvements. Some had me thinking ‘that’ll be useful’, some had me excited and some, to be honest, had me thinking ‘FINALLY!’

Here are some of my highlights:

Random

One feature that I’m especially pleased about is random. Random has always been a sticking point for me in Swift — arc4random , arc4random_uniform , and drand48 have seemed out of place — more like an artifact from ancient history than a part of a ‘modern’ language, and in fact, they were! These methods directly accessed lower level C APIs.
arc4random and arc4random_uniform used and returned the little used UInt32 type ( Int and UInt are much more common in Swift, which automatically uses either the 32 or 64 bit version depending on the platform your app is running on.) This means that the parameter being passed and the response always had to be converted, making a request for random extra verbose. Want a random integer between 0 and 10? Take a look at this:

let max = 10
//pre Swift 4.2
let result = Int(arc4random_uniform(UInt32(max)))

Wow. See what I mean? And if the laborious syntax isn’t a convincing enough reason — arc4random didn’t return uniform distribution of random numbers, drand48 (though it did return more useful data type Double) required an additional step of seeding, and let’s be honest — these methods had horribly ugly names!
Well — breathe a sigh of relief because Swift 4.2 has a new and exciting API with a whole range of convenience methods to make our lives easier as developers.
Remember the random integer between 0 and 10? How about this:

let max = 10
//Swift 4.2
let result = Int.random (in: 0 ..< max)

Much simpler and more readable, right? And it doesn’t have to be an integer, all numeric types have a random method now — here’s the Double version:

let max = 10
//Swift 4.2
let result = Double.random (in: 0 ..< max)

There are even collection convenience methods that select a random element.
Want to pick a suit, any suit? Too easy now:

var suits = ["Hearts","Diamonds","Clubs","Spades"]
//Swift 4.2
let suit = suits.randomElement()!

Want to shuffle the suits? Just as easy:

//Swift 4.2
suits.shuffle()

You can check out the Swift Evolution proposal for random unification here.

Bool toggle

Speaking of neat little convenience methods, here’s another!
You can now simply call the toggle method on a Bool.
No more:

//pre Swift 4.2
soundOn = !soundOn

You can now do this:

//Swift 4.2
soundOn.toggle()

You can check out the Swift Evolution proposal for adding toggle to Bool here.

New Collection higher order functions

When higher order functions come up, people often discuss the big four — map, filter, reduce and sort. In my blog post on higher order functions in Swift, I looked at a whole bunch of other higher order functions that collection types offer. Well, in Swift 4.2 we have more!

allSatisfy
Whereas the contains method returns a Bool based on whether at least one element in a collection satisfies a condition, the new allSatisfy method returns a Bool based on whether all elements satisfy a condition. For example:

var fruits = ["Banana","Banana","Coconut","Banana","Banana"]
//Swift 4.2
let completelyBananas = fruits.allSatisfy { $0 == "Banana" } //false

Check out the SE proposal here.

firstIndex and lastIndex
We previously had methods index(of:) and index(where:) which found the first item which satisfied a condition. We now have lastIndex(of:) and lastIndex(where:) too, which finds the last item in the collection that satisfies a condition. It made sense then to change the name of the index methods to firstIndex(of:) and firstIndex(where:).
You can find the SE proposal for first and last methods here.

removeAll
Remember the confusion you had when you first tried to remove all items from an array that satisfied a condition using a simple for loop?
You may have programmed something like:

var fruits = ["Banana","Banana","Coconut","Banana","Banana"]
//remove all bananas (naive implementation)
for (index,fruit) in fruits.enumerated() {
if fruit == “Banana” {
fruits.remove(at: index)
}
}

Then everything really did go bananas when an Index out of Range error appeared in the console?

Ah for more innocent days.
Of course the index had continued to increment while the number of elements in the array steadily decreased, until finally the loop index was higher than the number of elements in the array, causing a crash.

There were solutions to this problem of course — loop in reverse, for example, or use the filter method, but now we have a method built for just this task, removeAll. Take a look:

var fruits = ["Banana","Banana","Coconut","Banana","Banana"]
//remove all bananas (Swift 4.2)
fruits.removeAll { $0 == “Banana” }

Well,​ that was easier! You can find the SE proposal for remove all collection method here.

Looping through enumerations

I remember years ago having an enumeration nicely set up — I think it was something like an enum for card suits…

enum Suit {
case hearts
case diamonds
case clubs
case spades
}

…and I remember realizing I needed to loop through the cards. (Perhaps it was to find a random suit) I remember thinking — well that shouldn’t be so hard, I already have the enum set up, right?
I then realized that this isn’t a default feature of enums, and I remember thinking, “whaaa?”

Of course,​ there was a way around this — you could set up a static variable for example that contained an array of all the items in the enum:

//pre Swift 4.2
enum Suit {
case hearts
case diamonds
case clubs
case spades
static var allCases:[Suit] = [.hearts, .diamonds, .clubs, .spades]
}

You could then use this allCases property to loop through the cases:

for suit in Suit.allCases {
print(suit)
}

Well, Swift 4.2 (FINALLY!) can automatically synthesize this for you. All you need to do is adopt the CaseIterable protocol.

//Swift 4.2
enum Suit:CaseIterable {
case hearts
case diamonds
case clubs
case spades
}

Imagine — combined with the new collection convenience methods, we could now shuffle your enum case suits:

//Swift 4.2
var suitsShuffled = Suit.allCases.shuffled()

Or pick a random suit!

//Swift 4.2
var pickASuitAnySuit = Suit.allCases.randomElement()!

Wow! You can find the SE proposal for the all cases property for enums here.

Well — that’s plenty to be excited about with Swift 4.2, and I haven’t even covered everything new. If you’re interested in reading about other proposals I haven’t mentioned that made it into Swift 4.2 or perhaps are on their way for Swift 5, you can take a look over at the Swift Evolution page.

Interested to learn more on using Swift for building apps in iOS?

Click on the link to check out my livevideo course, iOS Development with Swift in Motion. You can check out an intro video here, and if you’d like to see a slide deck with more info click here.