A new version of the Swift programming language is here: Swift 5.0. It’s released in March 2019, with a fair number of changes. How does this Swift update affect practical iOS development? And who’s making these changes anyway? In this tutorial, we’ll walk through some of the proposed and accepted changes for Swift 5.0. We’ll also discuss how the process of making changes to the Swift language works, and why that’s relevant for iOS developers. The goal of this tutorial isn’t to provide you with an exhaustive list of upcoming Swift 5.0 changes (that’s impossible), but to instead give you some insight into how the Swift language is being developed. It’s also an opportunity for Swift developers to learn more about Swift, its contributors, and what goes into developing a programming language.
Table of Contents
How The Swift 5.0 Update Works
The Swift programming language first appeared in 2014. Swift is stable to use in production apps, but the language is also actively being developed. About five years later, we’re already at version 4.2! At the end of 2015, the Swift language has been open sourced. That means that anyone can read, copy and modify the source code that makes up the Swift language. As a result, the open source community now actively improves the language – with 600+ contributors. Swift was originally the “second” language for apps in the Apple ecosystem (iOS, macOS, tvOS, watchOS) next to Objective-C. But since it’s open source, Swift can be used on a number of other platforms, most notably Linux and Ubuntu. This lead to the development of server-side Swift, i.e. using Swift as a back-end development language for webservices. Why discuss all this? It’s important to realize that Swift is much bigger than building iOS apps – and as you’ll soon see, this is even more true for Swift 5.0. In short, updates to the Swift programming language go according to this process:- Changes to the Swift programming language are proposed and discussed on a GitHub repository called Swift Evolution.
- Anyone can propose changes to the language, but there’s process that needs to be followed. You’ll find that many proposed changes are first discussed in the Swift Forums, and in communities beyond.
- Proposed changes are publicly reviewed by the Swift core team, consisting of (former) Apple engineers like Chris Lattner and Ted Kremenek. A list of current and past proposals can be found on Swift Evolution, in the proposals directory.
- Proposals typically include source code or technical designs. Eventually, if a proposal is accepted, the source code for the change is merged into the Swift source code. (Yes, programming languages are programmed, too!)
- And of course, proposals can be rejected too. A rejected proposal that’s worth checking out is SE-0217, about the bangbang operator !!. This proposal is fairly easy to understand, and has lead to good discussions and insights in the Swift developer community. It’s a good example of how Swift Evolution is about more than just creating a good programming language.
The Goal For Swift 5.0: ABI Stability
The main focus for Swift 5.0 is to reach ABI stability. The term “ABI” stands for Application Binary Interface. It’s the binary equivalent of an API, an Application Programming Interface. As an iOS developer, you use the API of a library to write code for your apps. The UIKit framework, for example, includes an API to interface with buttons, labels and view controllers. You use that API as a developer, just like you use the steering wheel to drive a car. Some APIs are private, such as your car’s odometer. Roughly speaking, the steering wheel connects internally to the wheels of your car. When you steer the car, via the steering wheel “API”, the car turns. The way the steering wheel connects to the car’s wheels is the Application Binary Interface (ABI). Internally, the steering wheel is connected to a shaft between the car’s wheels that turns the wheels. You have no control over how this system works – the only thing you can do is steering. When a user downloads and installs your app, they’re not downloading all the code that your app needs to execute properly. Much of that code is already present on their iPhone, as part of iOS, and its frameworks and libraries. Your app can use the binary code already present, via the ABI. But what if your app uses a different version of a certain framework? Different versions mean different APIs and ABIs. Oops! Fortunately, most iOS versions are backward (and forward) compatible, at least for a few iOS versions. Apps compiled with the iOS 11 SDK run on iOS 10, and vice versa (some exceptions apply here). Let’s get back to Swift now. The problem with Swift is that its Application Binary Interface (ABI) isn’t stable. It’s not stable enough to ship as part of iOS, like other frameworks and libraries. ABI stability in this sense means that any future compilers of Swift need to be able to produce binaries that can run on the stable ABI that’s part of iOS. The Swift core team isn’t confident yet that the ABI is stable enough to be shipped as part of iOS, but that’s going to change with Swift 5.0. The solution so far has been to ship iOS apps that use Swift with the Swift dynamic binary itself. Instead of connecting to the OS, every app links to their own specific version of Swift! The main advantage is that app developers can develop apps with Swift, while Swift is actively being developed, without running the risk of ABI incompatibility. Changes to Swift can be distributed without updating iOS. This has negative consequences, too:- When an ABI is stable, operating system vendors can safely include the Swift binary interface with releases of their operating system. This severely impacts the adoption of Swift outside of the Apple ecosystem.
- Every Swift app ships with a version of the Swift dynamic libraries. This takes up storage space and bandwidth – it’s a waste of resources.
- A stable ABI means that the language cannot change in major ways, and less frequent, because the Swift library is shipped with iOS. For those who remember the Swift 2 to 3 migration, this is a good thing…
- Developers will be able to distribute pre-compiled frameworks, i.e. binaries, of their libraries. This means you don’t have to compile a library before using it, which affects Xcode compile times, but also paves the way for Swift-based commercial libraries and binary packages for Linux.
Filter And Count With “count(where:)”
The proposed count(where:) function has been retracted for the Swift 5.0 release, because of performance issues, but it’s hopefully coming back in a future version of Swift. SE-0220 describes a new function on collections that combines filter(_:) and count in one function call. You’re already familiar with collection functions like map(_:), reduce(_:) and filter(_:). You use filter(_:) to find and return array items that conform to a given predicate, passed as a closure. Let’s look at an example. In the code below, we’re using filter(_:) to filter out numbers from scores that are greater than 5. let scores = [1, 3, 8, 2, 5, 6, 2, 10] let result = scores.filter({ $0 > 5 }) print(result) // Output: [8, 6, 10] In practical iOS development, you often want to find/filter values from an array – and then just count them. Here’s the same example, using the count property to find the number of filtered items: let scores = [1, 3, 8, 2, 5, 6, 2, 10] let count = scores.filter({ $0 > 5 }).count print(count) // Output: 3 The above code has two problems:- It’s a bit too verbose. First we’re filtering, and then we’re counting, even though we really only want to count. And when reading, it’s easy to miss the .count at the end, too.
- The above code is wasteful. The intermediate result of the filter(_:) operation is discarded. It’s like copying the apples from a fruit basket, only to throw them away once you’re done counting.
Integer Multiples With “isMultiple(of:)”
A common use case in practical programming is testing if one number is divisible by another number. Many, if not most, of these tests involve checking if a number is even or odd. The default approach is to use the remainder operator %. The code below checks if the remainder of 5 divided by 2 is equal to 0. It’s not, because the remainder is 1. As such, 5 is an odd number. let result = 5 % 2 == 0 print(result) // Output: false SE-0225 proposes and implements a new function isMultiple(of:) for integers that checks if a given number is a multiple of another number. Here’s how you use it: let number = 42 if number.isMultiple(of: 2) { print("\(number) is even!") } Simple, right? Reasons for including it in the Swift standard library were:- It improves readability of your code, because the sentence reads like common English: if number is multiple of 2.
- Functions are discoverable by using code completion in Xcode, so that may help developers who are unaware of the % operator, or can’t find it.
- It’s not uncommon to make mistakes with the % operator, and its implementation differs across languages a developer may use.
The Result Type
SE-0235 is pretty cool, because it adds an entirely new type to Swift: Result. You already know how to handle errors in Swift with do-try-catch, right? You also probably know that many functions still pass Error or NSError values, from async APIs for example. In this tutorial about URLSession you can see first-hand how complex it is to handle different kinds of errors elegantly. You basically need 2-3 different mechanisms to deal with try, Error and guard value != nil .... The community responded to this issue by introducing a Result type in their projects. This type encompasses two states of a passed result: success or failure. And because this type is so widely used, it’s now being added to the Swift standard library. This is the proposed solution: public enum ResultHandling Future Enum Cases
SE-0192 proposes a solution to the following conundrum:- When you switch over an enum, you’ll need to do so exhaustively (i.e., add a switch case for every case in the enumeration)
- You may need to add a case to an enum in the future, which is a code-breaking change for any switch that uses that enum
- Enumerations in the Swift standard library, and imported from elsewhere, can be either frozen or non-frozen. A frozen enumeration cannot change in the future. A non-frozen enum can change in the future, so you’ll need to deal with that.
- When switching over a non-frozen enum, i.e. one that can change in the future, you should include a “catch-all” default case that matches any values that the switch doesn’t already explicitly match. If you don’t use default when you need to, you’ll get a warning.
Flatten Nested Optionals With “try?”
Nested optionals are… strange. Here’s an example: let number:Int?? = 5 print(number) // Output: 5 The above number constant is doubly wrapped in an optional, and its type is Int?? or OptionalThe New “compactMapValues()” Function For Dictionaries
The Swift standard library includes two useful functions for arrays and dictionaries:- The map(_:) function applies a function to array items, and returns the resulting array, while the compactMap(_:) function also discards array items that are nil
- The mapValues(_:) function does the same for dictionaries, i.e. it applies a function to dictionary values, and returns the resulting dictionary – but it doesn’t have a nil discarding counterpart
Further Reading
Pfew! And that’s not even everything that’s changing in Swift 5.0… In this tutorial, you’ve learned why and how Swift changes, and we’ve looked at a few interesting examples of upcoming changes for Swift 5.0. Fortunately it’s mostly good news, and Swift doesn’t change that much, but some of the changes are definitely code-breaking. The main goal for Swift 5.0 is to reach ABI stability, and we’ve discussed what that means. It’ll become easier to package Swift with an operating system, and it’s a big milestone for the maturity of the Swift language.Related Articles
- 10 Best Cool Websites To Let Your Creativity Thrive
- Top 51 Best Free Bold Fonts: Mastering Impactful Design
- Best Cold Email Software You Need To Close Deals
- Learn Python Programming – A Beginner’s Guide
- What is an NFT Drop [Everything to Know About NFT Drops]
- Answered! How to Perfect the Art of Sales Prospecting
- Super Easy Ways to Enhance the Image Quality
- 8 Best Tips to Create Effective Customer Surveys
- How to Integrate Chatbot with Your Website in 5 Easy Steps
- TikTok Video Size: The Definitive Guide To TikTok Video Size
Most Popular Posts
- What is A Smart Contract in NFTs?
- Top 13 Freshworks Alternatives in 2023
- How to Make a Brochure: Tips to Create a Brochure with free Templates
- What is Creativity? A Comprehensive Guide to Understanding Today’s Most Important Ability
- Slack vs. HipChat : Choosing the Best Communication Tool for Your Team