Swift 6 Highlights: Key Features You Should Know

Swift 6 Highlights: Key Features You Should Know

Swift has completed a 10-year milestone this year since it was announced at WWDC 2014. A year after its announcement, Swift was open-sourced and was available on Linux. Swift Package Manager was introduced with Swift 3.

One of the major Swift releases came in 2019, Swift 5. In this, Apple introduced Stable ABI for Apple platforms which decreased the download size of the application as the Swift standard library became the part of OS and we do not have to bundle them in each of our applications separately. Along with this also came SwiftUI which leverages Swift's unique features to build UI apps better and faster.

Swift 6 is a major update five years after the Swift 5 release. Swift 6 improves codability, performance, and the overall developer experience.

In the below sections, we will discuss some of the key achievements, new places where Swift is available, and some of the new language features including the new language mode, Swift 6.

Cross-compilation to Linux

Cross-compilation is a common development use case. With cross-compilation, we can generate an executable on one environment and run it on a different environment.

Now cross-compilation will also support Linux wherein we can build our app on a macOS environment and deploy it on a Linux server.

To achieve cross-compilation in a Linux server, follow the below steps:

  • Firstly, create the service on macOS for the macOS host.
  • Then, use the fully static Linux SDK for Swift to cross-compile from macOS to the Linux host.
  • This gives us a statically linked binary that can run on any Linux machine without needing an additional runtime to be installed.

We can download the SDK preview at swift.org/install.

Swift Testing

Swift Testing is a new framework, that is approachable, expressive, flexible, and scalable. It takes advantage of modern Swift features such as macros and integrates with concurrency.

The package is developed in open source with cross-platform compatibility. It is designed to be seamlessly integrated with multiple IDEs such as Xcode and VSCode.

Some of the features of Swift Testing are:

  • To declare a test, we add the @Test attribute to our function. We can also provide a custom display name as an argument to the @Test("Name") attribute which increases the readability of the test and lets us know what the test case has been created for.
  • #expect is used to verify the result, which is a macro, and determine whether the test is successful or not.
Example of writing a test case with Swift Testing
  • Swift Testing allows us to use tags to organize and filter our tests. We can also use arguments to avoid duplicating the same test for multiple inputs.
Tags and arguments

Language Updates

Swift 6 introduces a new language mode that achieves data race safety, expanding Swift's safety guarantees to concurrent programs.
We also have a new language subset called Embedded Swift which can run on highly constrained systems. Along this Swift 6 has many new improvements which makes it even better.

Let's start one by one over the new language updates.

NonCopyable types

  • All Swift types, whether it is value types or reference types are copyable by default. Noncopyable types suppress this behavior, making it useful for scenarios where we use them as unique types.
    For example, a unique system resource such as a file can be represented as a Noncopyable struct with a deinitializer that automatically closes it. This prevents runtime issues like multiple writers to the same file. It also prevents resource leaks which are easy to introduce without automatic cleanup.
  • However, this representation is still not ideal. The initializer takes an open file descriptor that is unsafe. We may add some code before opening a file and initialization that terminates the program. The deinitializer never gets to run resulting in a resource leak.
  • We can fix this with a failable initializer, that takes a file name, opens the file, and finishes initialization if the filename is valid. This initializer returns an optional of the Noncopyable file type.
  • Swift 5.10 support for Noncopyable types was limited only to concrete types. Swift 6 introduces support for Noncopyable types in all generic contexts as well as crucial generic types like Optionals, Results, and Unsafe Pointers.
  • The ability to abstract over both copyable and noncopyable types generically increases the useability of noncopyable types.

C++ Interoperability

  • Swift can interoperate directly with C++, providing a seamless developer experience and zero bridging costs. Now, with Swift 6, C++ virtual methods, default arguments, move-only types, and crucial C++ standard library types can be directly imported into Swift.
  • Interoperability involves mapping similar language concepts and making necessary changes to match semantics. C++ virtual methods and default arguments are mapped to the equivalent Swift versions.
  • C++ move-only types like the Person type are mapped to a noncopyable type in Swift.
  • The Swift compiler inserts then calls to the C++ move constructor when required.
  • Swift compiler will also show an error if we unintentionally try to copy the noncopyable value.
  • C++ is a widely used language but its lack of safety guarantee leaves it open for security attacks. We can adopt Swift in our C++ projects to improve security.
  • On Mac, the finder now uses C++ interoperability.

Typed throws

  • Swift has one of the best error-handling supports for throwing, propagating, and error-catching when any exception occurs.
  • Errors conform to the error protocol and we can write functions that throw errors with the throws keyword. Thrown errors are type erased and appear as Any error type in the catch handler. To know the error type we have to insert a dynamic type check to handle error cases explicitly.
  • Type eraser also involves boxing and unboxing. In highly constrained systems without runtime allocation capabilities, this presents a challenge.
    Swift 6 introduces typed throws to overcome this. Typed throws let us specify the error type along with the throws keyword.
    There is no type eraser involved and the error appears in the catch block with its concrete type.

Along with Typed throws and other updates discussed, the Swift 6 compiler has several other improvements to the language. Few are:

In addition to these updates, the Swift 6 compiler has a new Swift 6 language mode that achieves Data-race safety by default.

Data-race safety

  • Data races are a common programmatic error when writing concurrent programs. They occur when multiple threads are sharing data and one them tries to mutate it. Data races lead to unexpected runtime behavior, program crashes, and hard to reproduce issues.
  • Swift concurrency was designed around mechanisms to achieve data isolation, actors for protecting mutable states, and Sendable for safe data sharing.
    Swift 5.10 achieved data-race safety under the complete concurrency checking flag.
  • In Swift 6, data-race safety is achieved by default turning all the data-race issues in our app into compile-time errors, improving the security of our app, and reducing time in debugging these errors.
  • We have to make adjustment in our current language code to adopt the new language mode. We can add it module by module and even interoperate with dependencies that may or may not have migrated to the Swift 6 language mode.
  • Data-race safety is the only update governed by enabling the Swift 6 language mode. All the other updates are available by default when we update to the Swift 6 compiler.

To sum up

Swift 6 introduces compile-time data-race safety to prevent concurrency issues, ensuring safer multi-threaded code. Noncopyable types are added, enhancing performance by preventing unintended data duplication and improving resource management. The update also brings improved C++ interoperability, facilitating smoother integration of C++ libraries and features​​. Typed and untyped throws are introduced for more predictable and type-safe error handling​. Additionally, the testing framework now supports customizable test names, tagging, and parameterized tests, streamlining the testing process and improving readability.

These updates make Swift 6 a more powerful, safe, and user-friendly language, suitable for a wide range of applications from mobile and desktop apps to server-side and systems programming. For more detailed information, you can check out the Apple Developer website.​