Swift5.3 introduces a number of new features, not only in the language itself, but also enhanced Xcode support for Swift and Swift Packages updates. This article is not intended to cover all of the updates (and it’s not necessary), but rather to explore some of the important and interesting features. If you want to take a closer look at them, WWDC20 also has a number of sessions devoted to them, all of which have been compiled and posted at the end of the article.

Code indentation

Xcode12 has made a number of improvements to code indentation, mainly in the following areas:

  • Chained method calls, especially those involving nested or trailing closures
  • When elements are aligned, multi-line expressions in arguments, argument lists, arrays, and dictionary text or tuples are no longer indented
  • Multi-line conditional statements (if, guard, and while)

In the case of guard, the indentation was pretty stiff up to this point, the conditions always didn’t align with the first one, and the indentation inside the pack was problematic

Xcode12 is much more comfortable

Thank you Apple Dad for satisfying my ocD πŸ™πŸ™πŸ™

@escapingImplicit self in closure

Previously, it was stated that the closure of @escaping required explicit use of self, but Swift now allows implicit use of self in the closure of @escaping if the developer can determine that there is no circular reference.

If the user has already explicitly captured self in the closure’s capture list, self is now allowed to be used implicitly in the @escaping closure

class Test {
    var x = 0
    
    func execute(_ work: @escaping (a) -> ()) {
        work()
    }

    func method(a) {
        execute { [self] in
            x += 1}}}Copy the code

Also, if self is a value type, implicit self is also available in the @escaping closure without explicit capture:

struct Test {
    var x = 0

    func execute(_ work: @escaping (a) -> Void) {
        work()
    }

    mutating func method(a) {
        execute {
            x += 1}}}Copy the code

Reference to property ‘x’ in closure requires explicit ‘self.’ to make Capture semantics explicit.

Reduced incremental compilation

If you have a class that contains multiple classes, structures, or protocols,

struct A {}struct B {}...Copy the code

Before, for example, if you changed A, any file using A or B would be recompiled, but now only files using A would be recompiled, which would give A nice speed increase.

If problems are encountered during compilation, add -disable-type-fingerprints to Other Swift Flags to disable them. If you still have problems, add -disable-fine-grained dependencies to disable the new dependency infrastructure.

Binary Size

Apple has been optimizing binary sizes since Swift 4, all the way through version 5.3, from 2.3 x to 1.5 x.

The official explanation for why Swift needs so many binary sizes is that Swift has some “security” related features that require a certain amount of code implementation in the generated product.

The official Demo shows a 43% drop in compilation results using Xcode12 compared to Xcode11.

Swift Platform Support

Updated support for multiple platforms, including:

  • Apple’s OS
  • Ubuntu 16.04, 18.04, 20.04
  • CentOS 8
  • Amazon Linux 2
  • Windows (Coming Soon, Swift 5.3)

For non-APP development of the students useful, snail just porter πŸ™ƒ.

Dirty Memory optimization

As the dirty memory can not be recycled by the system, it is of course good to reduce the dirty memory effectively. After the official test, the heap memory usage is compared:

Emm….. It’s not obvious.

Code completion

Apple has made some minor optimizations to support code completion for more scenarios. A useful example is the support for completing ternary expressions:

It’s still a small game, but Apple has announced that Xcode12 will have a big boost in completion speed. In some scenarios, the performance is up to 15 times better than Xcode11.5.

According to Apple’s integrity, I don’t believe the optimization of 15 times. WWDC19 said that the App startup speed was greatly optimized compared with the last version, but in fact, the startup speed of the last version has been greatly increased compared with the last version, and the final optimization effect is not so exaggerated.

Multiple trailing closures

Swift5.3 previously supported only the last closure argument that could be used with trailing closures:

UIView.animate(withDuration: 5, animations: {
    // ...{}) (_) in
    // ...
}
Copy the code

Swift now supports multiple trailing closures and looks more elegant (I like it😍) :

UIView.animate(withDuration: 5) {
    // ...
} completion: { (_) in
    // ...
}
Copy the code

Try catch supports multiple modes

Before Swift5.3, try… catch… In the case of multi-error type judgment, certain redundancy will be caused to the code, for example:

Swift5.3 extends try… catch… Syntax that makes it possible to catch different errors, like switch… case… :

Compare Enum

In Swift5.3, having an enum comply with the Comparable protocol enables comparison, a very useful extension.

Enumerated cases support protocol ι•Ώ 难 ε₯ 🧐

Before Swift5.3, enums had to implement methods in Protocol and could not directly use cases instead.

protocol Foo {
  static var bar: Self { get }
  static func baz(arg: Int) -> Self
}

enum SomeEnum: Foo {
    static var bar: SomeEnum {
        return ._bar
    }
    
    static func baz(arg: Int) -> SomeEnum {
        return ._baz(arg: arg)
    }
    
    case _bar
    case _baz(arg: Int)}Copy the code

The above approach is cumbersome to use, and Swift5.3 has optimized it so that cases can be considered as an implementation of Protocol without having to write duplicate code.

protocol Foo {
  static var bar: Self { get }
  static func baz(arg: Int) -> Self
}

enum SomeEnum: Foo {
    case bar
    case baz(arg: Int)}Copy the code

newFloat16

The previous Float32 and Float64 are aliases for Float and Double respectively. Float16 is a new IEEE 754 standard floating-point format.

Advantages:

  • Better performance: With only two bytes of memory, twice as much can be held in SIMD registers or memory pages, which typically doubles performance on supported hardware.
  • Interoperability with __fp16 types in C/Objective-C

Disadvantages:

  • Obviously, low precision and small range

@mainDeclare entry functions

After ArgumentParser was released, people wanted an annotation like @UIApplicationMain to declare entry functions, and the Windows platform supported multiple entry function types, so main.swift didn’t fit well.

Swift5.3 supports annotating declarative entry functions with the @main keyword:

Those interested can browse @main: Type-based Program Entry Points.

Numerics library

Numerics is an open source Swift library from Apple that provides an easier way to perform numerical calculations using floating-point types in all of the standard libraries, covering almost all basic mathematical functions, via generic constraints.

As a Swift only library, Numerics is a good example of how to write and encapsulate more elegant Swift code.

Package Manager

It has been four years since Swift Package Manager was released, and this year has brought two very important features:

  • Binary dependent distribution
  • Resource file

Emm…… Cocoapods not fragrant 🀭, follow-up research to supplement.

New Logger

Logger collects and processes log information to understand and debug unexpected behavior in applications. During development, you often encounter bugs that are difficult to reproduce or cannot be debugged directly. Logger helps developers understand and deal with such problems.

It’s also easy to use:

import os

func test(a) {
    // subsystem is used to distinguish which application's log. Can use the bundleID
    // Category is used to distinguish which module is the application
    let logger = Logger(subsystem: "com.example.TestWWDC20", category: "testos")
    logger.log("Started a task \(taskId)")}Copy the code

Under singleton encapsulation, add business module support, which is easy to use and convenient for unified management.

  • Performance optimization

Since logs are usually of large magnitude and read and write can affect performance, the online version eliminates unnecessary log printing, such as through the print function. To solve this problem, Swift and Xcode are highly optimized to convert log information to a string only when it is actually displayed.

  • Privacy protection

To protect privacy, when non-digital data is added to log messages, it is marked private by default to ensure that personal information is not leaked when the application is running on the real machine.

Of course, log information also supports explicit marking of privacy levels by the developer:

So how does that compare to non-public logs? Logger provides an equal-Preserving hash method. After processing, it doesn’t show real data, but it does allow us to determine if the two pieces of information are the same.

If the application is launched from Xcode, even if the log information is private, it will be fully displayed in the Console for developers to debug.

  • The log level

Swift provides five different levels: Debug, Info, Notice (default), Error, and Fault.

The ability to persist logs varies with different levels:

Accordingly, their performance is also different:

As you can see, the performance of Debug logging is fast, so it is safer to call time-consuming functions:

  • formatting

Logger supports formatting of written parameters for easy reading and comparison of data:

With formatting, the data is clear and easy to copy to Numbers:

Related to the Session

  • What’s new in Swift
  • Swift packages: Resources and localization
  • Distribute binary frameworks as Swift packages
  • Explore logging in Swift
  • Explore numerical computing in Swift

It’s not easy to create the article, any mistake, welcome to feng comment (Diao), please click on πŸ‘, thank you very much!