I am following Stanfords' CS193p Developing Apps for iOS online course.
It is using the Grand Central Dispatch (GCD) API for a demo of multithreading. But they noted, that
"GCD has been mostly replaced by Swift's new built-in async API as of WWDC 2021".
So I wanted to learn how the code from the Lecture would look like after updating it to use this new API.
After watching Apple's WWDC videos, it seems to me like
DispatchQueue.global(qos: .userInitiated).async { }
is replaced in this new async API with Task { }
or Task(priority: .userInitiated) {}
, but I'm not sure, what has DispatchQueue.main.async { }
been replaced with?
So, my questions are:
- Am I correctly assuming, that
DispatchQueue.global(qos: .userInitiated).async { }
has been replaced withTask(priority: .userInitiated) {}
- What has
DispatchQueue.main.async { }
been replaced with?
Please help, I want to learn this new async-await API.
Here's the code from the Lecture, using old GCD API:
DispatchQueue.global(qos: .userInitiated).async {
let imageData = try? Data(contentsOf: url)
DispatchQueue.main.async { [weak self] in
if self?.emojiArt.background == EmojiArtModel.Background.url(url) {
self?.backgroundImageFetchStatus = .idle
if imageData != nil {
self?.backgroundImage = UIImage(data: imageData!)
}
// L12 note failure if we couldn't load background image
if self?.backgroundImage == nil {
self?.backgroundImageFetchStatus = .failed(url)
}
}
}
}
The whole function (in case you need to see more code):
private func fetchBackgroundImageDataIfNecessary() {
backgroundImage = nil
switch emojiArt.background {
case .url(let url):
// fetch the url
backgroundImageFetchStatus = .fetching
DispatchQueue.global(qos: .userInitiated).async {
let imageData = try? Data(contentsOf: url)
DispatchQueue.main.async { [weak self] in
if self?.emojiArt.background == EmojiArtModel.Background.url(url) {
self?.backgroundImageFetchStatus = .idle
if imageData != nil {
self?.backgroundImage = UIImage(data: imageData!)
}
// L12 note failure if we couldn't load background image
if self?.backgroundImage == nil {
self?.backgroundImageFetchStatus = .failed(url)
}
}
}
}
case .imageData(let data):
backgroundImage = UIImage(data: data)
case .blank:
break
}
}
.userInteractive
forData(contentsOf: url)
in your original code. Instead, look at the asynchronous URL methods like usingURLSession
. hackingwithswift.com/books/ios-swiftui/… – Fdic.userInitiated
, not.userInteractive
in the Lecture. I will update the question. – WormsURLSession' is a better way to do this, but the Stanford professor was temporarily using GCD instead to **explain** multithreading. A few lectures later he changed that to
URLSession` – WormsDispatchQueue.global(qos: .userInitiated).async { }
has been replaced withTask(priority: .userInitiated) {}
2. What has DispatchQueue.main.async { } been replaced with? – WormsDispatchQueue.global(qos: .userInitiated).async { }
withTask(priority: .userInitiated) {}
? – Worms