What will be new in Swift 5?

Apple Swift 5 will be release in late 2018. The primary focus of Swift 5 will be ABI (Application Binary Interface) stability for the Swift Standard Library. Here the goals for Swift 5 -

1. ABI Stability

1.1 What is ABI Stability?

  • At runtime Swift binaries interact with other libraries and components through an ABI (Application Binary Interfaces). It defines low level details like how to call a function, how data is represented in memory and where metadata is and how to access it.
  • Currently Swift is not ABI stable, so each binary (App), bundles its own version of the Swift Dynamic Library. Swift doesn’t live on the iOS Operating System, it lives within each App.
  • That means any app (lets App1) is using Swift 3.0, so it bundles Swift 3.0 Dynamic Library (containing the 3.0 ABI) inside. But the any other app (let App2) is using Swift 3.2, so it bundles Swift 3.2 and it’s 3.2 ABI.
  • If Swift becomes ABI Stable, Swift will live within the iOS Operating System and it’s ABI will be compatible with every version of Swift. i.e App1 is using Swift 5.0, but App2 is using Swift 5.3, and their both consuming Swift ABI embedded in the Operating System.

1.2 Why does ABI Stability matter?

  • Bundle size will reduced
  • Language changes smaller / Less frequent
  • Less Migration
  • Developers can create Pre-compiled Frameworks in Swift (currently frameworks are compiled when compiling your app) because no need to embed Swift

1.3 Drawbacks

  • Limits changes to the Public Interfaces and Symbols
  • Restricts the ways Swift can grow and evolve

2. Async/Await Pattern

2.1 Async

  • Well known solution used in other popular programming languages - C#, Python, Javascript with great success.
  • Async keyword used similar to the existing throws keyword
  • Declare a function as async to indicate function is a Coroutine.

2.2 Await

  • Similar to the existing try keyword.
  • Indicates that non-local control flow can happen at that point.

2.3 Why Async/Await?

  • Asynchronous APIs are difficult to work. Error Handling, Callbacks, when performing multiple operations creates complicated control flows.
  • Made worse with Swift’s guard let syntax throughout callback closures.
  • Hard to know what Queue/Thread you’re on.

2.4 Example

To provide motivation for why it is important to do something here, lets look at some of the problems that Cocoa (and server/cloud) programmers frequently face. Sequence of simple operations is unnaturally composed in the nested blocks. Here is an example showing this, before you might write:

func loadWebResource(_ path: String, completionBlock: (result: Resource) -> Void) { ... }
func decodeImage(_ r1: Resource, _ r2: Resource, completionBlock: (result: Image) -> Void)
func dewarpAndCleanupImage(_ i : Image, completionBlock: (result: Image) -> Void)
func processImageData1(completionBlock: (result: Image) -> Void) {
   loadWebResource("dataprofile.txt") { dataResource in
      loadWebResource("imagedata.dat") { imageResource in
         decodeImage(dataResource, imageResource) { imageTmp in
            dewarpAndCleanupImage(imageTmp) { imageResult in
               completionBlock(imageResult)
             }
          }
       }
    }
}

whereas now you can write:

func loadWebResource(_ path: String) async -> Resource
func decodeImage(_ r1: Resource, _ r2: Resource) async -> Image
func dewarpAndCleanupImage(_ i : Image) async -> Image
func processImageData1() async -> Image {
    let dataResource = await loadWebResource("dataprofile.txt")
    let imageResource = await loadWebResource("imagedata.dat")
    let imageTmp = await decodeImage(dataResource, imageResource)
    let imageResult = await dewarpAndCleanupImage(imageTmp)
    return imageResult
}

3. Actors

3.1 What is an Actor?

  • Actors represent real world concepts like "a document", "a device", "a network request".
  • An actor is a combination of a DispatchQueue, the data that queue protects and messages that can be run on the queue.
  • An actor would be a new 'type' in Swift, like class, struct or protocol
  • An actor allows programmer to define internal variables and functions to
    manage that data and perform operations on it.
  • Actors can't return values, throw errors or have inout parameters
  • We can communicate with Actors asynchronously, and actors guarantee that the data they protect is only touched by the code running on that queue.
  • UIKit and AppKit would model something like the "Main Thread" using a MainActor
  • Programmers could define extensions to the MainActor in order to run their code on the main thread.
  • Actors are shutdown when their reference count reaches 0 and the last queued message is completed.

3.2 Example

Lets imagine we're building the data model for an app that has a tableview with a list of strings. The app has UI to add and manipulate the list. It might look something like this:

actor TableModel {
    let mainActor : TheMainActor
    var theList : [String] = [] {
        didSet {
            mainActor.updateTableView(theList)
        }
    }
    
    init(mainActor: TheMainActor) { 
        self.mainActor = mainActor 
    }

    actor func add(entry: String) {
      theList.append(entry)
    }
  }

4. Other Improvements

  • String - Language level support for Regular Expressions. Performance Improvements to the internal implementation of String.
  • Standard Library Improvements
  • Foundation Improvements
  • Syntactic Additions

Source -



Related Article