Chapter 4. Changes to Swifts Core Will Have You Asking for More

Many of the libraries have been touched to pull off this effort including-the Swift standard library, all of Cocoa and Cocoa Touch frameworks, Core Graphics, and Grand Central Dispatch. With the release of Swift 3, we can expect changes that reduce the awkwardness of the language's link to Objective-C, exuding way more Swifty-ness. The Swift team has introduced new API guidelines with the intention of giving the language its own character. The result is a huge renaming and refactoring effort that flows throughout the language. Swift 3 has undergone a huge facelift in terms of its interaction with Objective-C and C APIs. The Swift team is aiming to make your development experience feel more like Swift and less like directly dumping Objective-C into your code. Swift is its own language and should have its own feel just like any other programming language. Yet prior versions of Swift were heavily influenced by the need to interact with Objective-C and C APIs.

In this chapter, we will quickly highlight the philosophies for writing good Swift APIs. Afterward, we will spend the remaining chapter on language improvements for referencing and using Objective-C features in Swift 3 and importing code from Objective-C and C to Swift 3. Every language change to Swift 3 is covered by one or more Swift Evolution proposals. As we cover a new feature, I'll also provide the proposal number that documents the rationale behind the change. While knowing the actual rational for a new feature is not critical to your understanding of how to implement its code, I think it is interesting to know the efforts and sometimes debates behind why a particular change was implemented. The Swift Evolution repository contains tons of information on accepted and rejected proposals. If you are a careful observer, you will also see proposals that were accepted for the Swift 3 release but didn't get implemented in time for the release.

Let's start with the proposals for the Swift API Design Guidelines. The Grand Renaming proposals represent, collectively, a very large undertaking and are covered by proposals SE-0005, SE-0006, SE-0086, and SE-0088. Implementing the API guidelines represents the largest change to the language for Swift 3. I couldn't possibly cover every API change resulting in the Grand Renaming proposals in this short book. Thankfully, you don't have to understand every line that changed in the libraries to be productive with Swift 3. You have two fantastic resources that will pay dividends with very little effort on your part. The first resource is the Swift migration tool which converts existing Swift projects to the latest syntax. When you use the Swift migrator, you can convert your Swift 2.2 projects to Swift 3 and receive most of the changes for free. The second extremely valuable resource is the Swift API Guidelines, which were developed to help make your code more Swifty. The Swift API Guidelines are based on the following principles as quoted on https://swift.org/documentation/api-design-guidelines/:

  • Clarity at the point of use:This is your most important goal. Entities such as methods and properties are declared only once but used repeatedly. Design APIs to make those uses clear and concise. When evaluating a design, reading a declaration is seldom sufficient, always examine a use case to make sure it looks clear in context.
  • Clarity is more important than brevity:  Although Swift code can be compact, it is a non-goal to enable the smallest possible code with the fewest characters. Brevity in Swift code, where it occurs, is a side-effect of the strong type system and features that naturally reduce the boilerplate.
  • Write a documentation comment: This for and every declaration. Insights gained by writing documentation can have a profound impact on your design, so don't put it off.

For more details on adopting these guidelines, please refer to the WWDC 2016 lecture on Swift API Guidelines at https://developer.apple.com/videos/play/wwdc2016/403/.

In Objective-C, we can use a type called a selector to reference the name of a method. Swift 2.2 introduced #selector expressions to remove the error-prone nature of providing string literals as the selector name. In Swift 3, the language builds on #selector expressions by allowing you to reference getter and setter methods. This feature allows us to refer to getter and setter properties of objects. Let's look at an example to see how we could access the setter for one of the properties on our ClassRoom class:

class ClassRoom: NSObject{ 
    var roomNum: String 
     
    init(roomNum: String){ 
        self.roomNum = roomNum 
    } 
} 
 
let classRoom = ClassRoom(roomNum: "1-D1") 
classRoom.perform(#selector(setter: ClassRoom.roomNum), with: "2-D3")

We can now access the setter for the roomNum using #selector(setter: ClassRoom.roomNum) or the getter using #selector(getter: ClassRoom.roomNum). Once we have our reference, we can use any of the NSObject perform methods available in Objective-C.