What’s New in Swift 4.2?

What’s New in Swift 4.2?

What’s New in Swift 4.2?

What’s New in Swift 4.2?

What’s New in Swift 4.2?
What’s New in Swift 4.2?
What’s New in Swift 4.2? What’s New in Swift 4.2? What’s New in Swift 4.2? What’s New in Swift 4.2? What’s New in Swift 4.2?

What’s New in Swift 4.2?

Final product image
What You’ll Be Creating

The second update release to Swift of 2018, Swift 4.2 introduces some great improvements to the language. Read this post to learn how they can help you write even better code.

Included in this version’s list of improvements:

  • SE-0194: Adds CaseIterable protocol to automatically generate an array of all the possible enum cases.
  • SE-0195: Dynamic member lookup syntactical sugar.
  • SE-0196: New compiler directives #warning and #error.
  • SE-0197: New removeAll(where:) method to perform optimized in-place filter for collections.
  • SE-0199: New toggle() method to easily toggle/flip boolean values.
  • SE-0202: New native random number generator.
  • SE-0206: New Hasher type to improve and simplify conformance to Hashableprotocol.
  • SE-0207: New allSatisfy() method to verify all elements in a sequence pass a condition. 
  • SE-0194: Conditional conformance improvements

Enum Case Iteration

First-up, Swift 4.2 introduces a new protocol for enums. If you conform your enums to the CaseIterable protocol, you will be able iterate through your list of enums in an array-like fashion, listing out all the possible cases. For example, take the following enum:

You can iterate through this enum list like an iterateable, using the new allCases property, as follows:

Dynamic Member Lookup 

A new attribute, @dynamicMemberLookup, has been added to allow the Swift compiler to utilize a subscript method when accessing properties so that you can provide dot syntax for arbitrary names, which are then resolved at runtime. This takes a leaf out of Python’s book of conventions. When defining a subscript, you pass in a dynamicMember along with a list of properties that you will return, as follows:

This example illustrates receiving a dynamic member as a string and returning a string, whilst looking up the member name in the dictionary. The following implementation illustrates how this works:

Instantiating the class, the first two properties are dynamically discoverable and will return the default value of the member in a type-safe String back, at runtime. The last property (gender) does not exist in the class and would return nothing back, since we used an empty string as the default when looking up return values. You are not restricted to returning Strings, you can in fact return anything from a dynamic member lookup, including closures. 

New Compiler Warning and Error Directives

This new features is a blast from the past for many who came from an Objective-C background, the consortium introduces (or re-introduces) compiler directives for Swift to flag issues in your code. The two directives are #warning and #error

The #warning directive helps developers mark a block of code that has issues so these will show up as a warning in Xcode. The #error directive however will force a compile-time error and is useful if for instance you want to force the developer looking to look at your code and to complete the block of code, for example adding his or her own API token or credentials in lieu of the placeholder. The following example illustrates the latter use case:

New Method to Perform In-Place Filter for Collections

Through the new removeAll(where:) method, developers can now perform in-place filtering on collections by passing a closure condition. Say you have an array of shirts, and want to remove a specific value, medium, you would have previously done something like:

With the addition of removeAll(where:), instead of filtering to remove, you can run a more memory-optimized operation that removes explicitly and in-place:

Easily Toggle or Flip Between Boolean Values

A simple but welcomed improvement, SE-0199 introduces boolean toggling through the toggle() method. In a familiar pattern, you would have something like the following:

With the addition of this new method, you could write instead:

New Native Random Number Generator

Surprisingly the language up until Swift 4.1 lacked a native random generator, forcing developers to instead rely on arc4random_uniform() to return a uniformly distributed random number. Now you can simply call the random() method along with a specific range to work with:

This method is supported on other numerical types beyond Int, including: Float, Double, CGFloat, Bool, and Array.

The Bool lets you get back a random true or false response. This proposal also called for two array-related methods, the shuffled() method that lets you randomize an array order, and randomElement() which returns a random element from an array. 

Here’s an example of how you would use the new shuffled() method:

We can also use the randomElement() method to improve the code we had earlier to get a random shirt size:

Improvements to Hashable Protocol Conformance

Swift has improved how your custom object types conform to the Hashable protocol—making it faster, more secure and simpler—through a new Hasher struct. Previously, whenever you created dictionaries or sets, you would have a type that conforms to Hashable which gives you an optimized hash for free. However, when implementing your own type that conforms to Hashable, you needed to create your own algorithm to calculate the hashValue by hand. 

Swift 4.1 improved this significantly by inferring what can be used to uniquely identify the object:

However when you have to work with a more complex object type you still needed to implement an algorithm to return a unique hashValue back. Swift 4.2 introduces the new Hasher struct that can calculate unique hash value for you:

To implement the new Hasher struct, you create a Hasher instance and provide the custom types you want to combine. The Hasher instance will create and return a unique hash. 

Ensure All Elements in a Sequence Satisfy a Condition

The final feature accepted into Swift 4.2 is SE-0207, which adds a new method, allSatisfy() to verify whether all items in a sequence conform to a certain sequence condition. While you were already able to use the contains method to verify whether an element in a collection satisfies a condition, the allSatisfy method returns a boolean based on whether the entire set of elements satisfy a condition.

The following implementation of allSatisfy asserts whether the entire sequence of shirtOrderPrices is satisfied by the condition of being over $20:

Conclusion

Swift remains a growing language with new features being added and debated all the time. You can track the most up-to-date list of proposals, and the acceptance status of each one, by visiting Swift Evolution.