Updating Strings For Swift 4.2

The release of Swift 4.2 with Xcode 10 is getting close so it is time to look at the changes to the String API. These are my notes on what I changed when updating my Swift String Cheat Sheet for Xcode 10 and Swift 4.2

You can find the original and now updated guide and Xcode playground here:

Swift 4.2 Deprecations

The good news is that if you have been keeping up with Swift there is very little you have to change in your String code when upgrading to Swift 4.2. Most of the changes are new features in the underlying Collection and Sequence protocols you can choose to take advantage of when you are ready.

The only deprecation warning that I have in my String playground with the current beta is for the use of the characters view:

// Swift 3
var sentence = "Never odd or even"
for character in sentence.characters {
  print(character)
}

In Swift 4 a String became a collection of characters so the character view was no longer needed. In Swift 4.2 is has been deprecated. If you have not already done so you should migrate to using the String or Substring directly:

// Swift 4 and Swift 4.2
let sentence = "Never odd or even"
for character in sentence {
  print(character)
}

Finding Last Elements

Most of the improvements to String in Swift 4.2 come from improvements to the Sequence and Collection protocols that also apply to other types like Array.

For example, you can now find the last element that matches a predicate:

let alphabet = "abcdefghijklmnopqrstuvwxyz"
let lastItem = alphabet.last { $0 > "j" } // "z"

if let matchedIndex = alphabet.lastIndex(of: "x") {
  alphabet[matchedIndex]  // "x"
}

if let nextIndex = alphabet.lastIndex(where: { $0 > "j" }) {
  alphabet[nextIndex]  // "z"
}

The methods to find the first matching element still exist but have been renamed to be consistent with the above last methods:

// Swift 4 - soon to be deprecated?
alphabet.index(of: "x") {
alphabet.index(where: { $0 > "j" })

// Swift 4.2
alphabet.first { $0 > "j" }
alphabet.firstIndex(of: "x") {
alphabet.firstIndex(where: { $0 > "j" })

It seems likely the old methods will be deprecated by Swift 5 so you should probably migrate soon.

Random Element And Shuffled

SE-0202 Random Unification brings a new random API to Swift 4.2. This adds a randomElement method to Collection that we can use to get a random character from a String:

let suits = "♠︎♣︎♥︎♦︎"
suits.randomElement()

You can also iterate over a shuffled version of the character collection in a String:

for suit in suits.shuffled() {
  print(suit)
}

Other Minor Changes

When you want to convert a value to its String representation using something other than base 10:

let hex = String(254, radix: 16, uppercase: true)
// "FE"

let octal = String(18, radix: 8)
// "22"

Further Reading

Swift evolution changes in Swift 4.2 that are relevant to String: