Apple logo

Get ready for Swift 5.3!

By PhoenixDev | BE DEVELOPER | 12 Jun 2020


Swift 5.3 News

What is new in Swift 5.3 (whose publication process was announced by Apple on 3/25) can be found both at the code level (multi-pattern catch, multiple trailing closure …) and in the use of Swift Package Manager (addition of binary dependencies or resources. Below I detail some of the new features in Swift 5.3 (keep in mind that we expect to see the new beta of Swift 5.3 at WWDC20, although to test it you can download it at Swift.org).

Synthesized Comparable conformance for enums (SE-0266)

Thanks to this new addition, we can adopt the Comparable protocol in enums that do not have associated values, or that do have them and they adopt the Comparable protocol. With this, what is achieved is to be able to compare two cases of the same enum using, for example, > or <.

enum OperationOrder: Comparable {
    case addition
    case multiplication
    case exponent
}


let operation1 = OperationOrder.addition
let operation2 = OperationOrder.exponent


if operation1 < operation 2 {
    print("Do operation 2 first.")
} else {
    print("Do operation 1 first.")
}

Use where on contextually generic declarations (SE-0267)

What is looking for with this modification is to remove the restriction of attaching where clauses to member declarations that can only refer to external generic parameters. For example:

struct Operation<T> { }  


extension Operation where T.Element: Equatable {
    func doOperation() { // Code }
}
extension Operation where T.Element: Hashable {
    func recalculate() { // Code }
}
extension Foo where T.Element == Int {
    func resetOperation() { // Code }
}

With Swift 5.3 it can be expressed as:

extension Foo where T.Element: Equatable {
    func doOperation() { // Code }


    func recalculate() where T.Element: Hashable { // Code }


    func resetOperation() where T.Element == Int { // Code }
}

Redefinition of didSet semantics (SE-0268)

Prior to Swift 5.3, when using didSet in a property, the getter was always called to obtain the oldValue of that property (although this value was not referenced), with the consequent performance impact. In Swift 5.3 the efficiency of the process has been increased, since now the oldValue is not accessed if we are not calling it inside didSet.

Self use in closures is eliminated if no reference cycles are given (SE-0269)

Until now, inside closures it was necessary to use self explicitly, even if reference cycles were not going to occur. For example:

class Calculator {
    var result = 0


    func calculate(operation: @escaping () -> void) {
        operation()
    }


    func calculation() {
        calculate{[self]in
          self.result = 1
        }
    }
}

With Swift 5.3 self can be removed:

class Calculator {
    var result = 0


    func calculate(operation: @escaping () -> void) {
        operation()
    }


    func calculation() {
        calculate {
            result = 1
        }
    }
}

Multi-Pattern Catch Clauses (SE-0276)

Until now, Swift only allowed the use of one error type per catch block, allowing us to reduce duplicate code in error handling. That is to say:

enum CalculateError: Error {
    case infinite
    case overflow
}


func doOperation() {
    do {
        try calculation()
    } catch CalculateError.infinite {
        print("Infinite result")
    } catch CalculateError.overflow {
        print("Overflow error")
    }
}

Now with Swift 5.3 we can merge both errors into a single catch block:

func doOperation() {
    do {
        try calculation()
    } catch CalculateError.infinite, CalculateError.overflow {
        print("Can't do operation")
    }
}

A new Float16 type (SE-0277)

In Swift 5.3 this new type is added due to its widespread use in mobile graphics, HDR images and Machine Learning.

Multiple-trailing closures (SE-0279)

trailing closure refers to the fact that the last parameter of a function in Swift is a closure. In this case, Swift allows you to pass this closure directly inside the brackets instead of as a parameter:

func calculate(operation: () -> Void) {
    print("Initial steps")
    operation()
    print("Show result")
}


calculate() {
    print("Sum 1 + 1")
}

With Swift 5.3 this option is not limited to the last parameter of the function, so now we have to add multiple closures to our functions (simply by adding new labels):

func calculate(values: [Int], operation: () -> Void, showResult: () -> Void) {
    operation()
}


func performOperation() {
    calculate(values: [1, 2]) { (operation)
        print("Perform operation")
    }, showResult: { (result) in
        print(result)
    }
}

Swift Package Manager improvements

For those of us who use Swift Package Manager to create and import Swift packages, Swift 5.3 presents some very interesting improvements:

  • Package Manager Resources (SE-0271). Now Swift packages can incorporate resources (images, audio …). But not only that, but certain rules may be applied to process these resources.
  • Package Manager Binary Dependencies (SE-0272). You can use dependencies in binary format, such as Firebase or GoogleAnalytics.
  • Conditional dependencies (SE-0273). This option will allow specifying which dependencies are added depending on the platform.
  • Localized resources (SE-0278). Along with the possibility of adding resources to Swift packages, they can be localized.

Conclusion

Swift 5.3 includes interesting improvements at the code or Swift package management level. But there are other improvements to look out for as well, such as the fact that Swift 5.3 will support platforms like Windows and new Linux distributions.

How do you rate this article?

3


PhoenixDev
PhoenixDev

Interested on Blockchain and Cryptocurrencies. Love photography.


BE DEVELOPER
BE DEVELOPER

Tutorials, Tips and Tricks about iOS Mobile Development.

Send a $0.01 microtip in crypto to the author, and earn yourself as you read!

20% to author / 80% to me.
We pay the tips from our rewards pool.