Understanding Swift concurrency
In Swift 5.5, Apple added support for writing asynchronous and parallel code in a structured way.
Asynchronous code allows your app to suspend and resume code. This allows your app to do things like update the user interface while still performing operations like downloading data from the internet.
Parallel code allows your app to run multiple pieces of code simultaneously.
You can find links to all of Apple's Swift concurrency videos during WWDC21 at https://developer.apple.com/news/?id=2o3euotz.
You can read Apple's Swift concurrency documentation at https://developer.apple.com/news/?id=2o3euotz.
During WWDC2024, Apple released Swift 6. With the Swift 6 language mode, the compiler can now guarantee that concurrent programs are free of data races. This means that code from one part of your app can no longer access the same area memory that is being modified by code from another part of your app. However, when you create a new Xcode project, it defaults to the Swift 5 language mode, and you have to turn on the Swift 6 language mode to enable this feature.
To view Apple’s WWDC24 video on migrating your app to Swift 6, click this link: https://developer.apple.com/videos/play/wwdc2024/10169/
To view Apple’s documentation on migrating your app to Swift 6, click this link: https://www.swift.org/migration/documentation/migrationguide/
To give you an idea of how Swift concurrency works, imagine that you are making soft-boiled eggs and toast for breakfast. Here is one way of doing it:
- Put two slices of bread into the toaster.
- Wait two minutes until the bread is toasted.
- Put two eggs in a pan containing boiling water, and cover them.
- Wait seven minutes until the eggs are cooked.
- Plate and serve your breakfast.
This takes nine minutes in total. Now think about this sequence of events. Do you spend that time just staring at the toaster and the pan? You'll probably be using your phone while the bread is in the toaster and the eggs are in the pan. In other words, you can do other things while the toast and eggs are being prepared. So, the sequence of events would be more accurately described as follows:
- Put two slices of bread into the toaster.
- Use your phone for two minutes until the bread is toasted.
- Put two eggs in a pan containing boiling water, and cover them.
- Use your phone for seven minutes until the eggs are cooked.
- Plate and serve your breakfast.
Here, you can see that your interaction with the toaster and pan can be suspended, then resumed, which means these operations are asynchronous. The operation still takes nine minutes, but you were able to do other things during that time.
There is another factor to consider. You don't need to wait for the bread to finish toasting before you put the eggs in the pan. This means you could modify the sequence of steps as follows:
- Put two slices of bread into the toaster.
- While the bread is toasting, put two eggs in a pan containing boiling water, and cover them.
- Use your phone for seven minutes until the eggs is cooked.
- Plate and serve your breakfast.
Toasting the bread and boiling the eggs are now carried out in parallel, which saves you two minutes. Great! Do note however that you have more things to keep track of.
Now that you understand the concepts of asynchronous and parallel operations, let's study the issues that an app without concurrency has in the next section.