[참고 영상]
https://youtu.be/fTtaEYo14jI
[학습 목표]
다른 종류들의 Task를 다루면서 Task가 무엇인지에 대해 알아보자!
[구현 방법]
1. image를 가져오는 함수를 2가지를 만들어서 가져오는 방법.
func fetchImage() async {
do {
guard let url = URL(string: "https://picsum.photos/200") else {return}
let (data, _ ) = try await URLSession.shared.data(from: url, delegate: nil)
self.image = UIImage(data: data)
} catch {
print(error.localizedDescription)
}
}
func fetchImage2() async {
do {
guard let url = URL(string: "https://picsum.photos/200") else {return}
let (data, _ ) = try await URLSession.shared.data(from: url, delegate: nil)
self.image2 = UIImage(data: data)
} catch {
print(error.localizedDescription)
}
}
fetchImage를 1과 2로 만들어서 2가지를 데려오게 만들자.
VStack(spacing : 40){
if let image = viewModel.image {
Image(uiImage: image)
.resizable()
.scaledToFit()
.frame(width: 200, height: 200)
}
if let image = viewModel.image2 {
Image(uiImage: image)
.resizable()
.scaledToFit()
.frame(width: 200, height: 200)
}
}
.onAppear{
Task {
await viewModel.fetchImage()
await viewModel.fetchImage2()
}
}
fetchImage2와 fetchImage2를 image로 가져와서 출력시켜보면....?
<실행 모습>
이미지는 요구했던 대로 2개가 뜨기는 하지만 시간차가 있이 2개가 뜨는 시점이 다르다.
해당 이유는
await viewModel.fetchImage2()
가 위에 있는
await viewModel.fetchImage()
가 완료되기까지 기다리기 때문이다.
이 두가지 코드는 비동기 코드이기 때문에 위에 있는 await을 기다리게 된다.
그러나 이제부터 우리는 최대한 빨리 여러개의 이미지를 뜨는 것을 요구할 때가 많을것이니 다른 방법을 알아보자.
Task {
await viewModel.fetchImage()
}
Task{
await viewModel.fetchImage2()
}
await이 위에 있는 작업의 종료를 기다린다면 이번에는 Task로 두가지를 따로 설정해서 synchronous하게 작업을 진행시켜 보자.
await Task.yield()
해당 구문을 쓰면 다른 Task가 먼저 시작될때 까지 sleep 효과를 준다. 즉, 해당 구문을 통해 우선순위와 관계 없이 다른 Task가 먼저 시작되게 만들 수가 있다.
<실행 모습>
코드를 위와 같이 바꾸니 최대한 빨리 2개가 모두 뜨는 것을 볼 수가 있다.
Task의 경우에는 synchronous코드 이기 때문에 await이 asynchronous코드라고 하더라도 await의 완료를 기다리지 않고 위에 있는 Task가 실행 된 바로 다음에 다음 Task를 실행하기 때문이다.
[코드]
import SwiftUI
class TaskBootcampViewModel: ObservableObject {
@Published var image: UIImage? = nil
@Published var image2: UIImage? = nil
func fetchImage() async {
do {
guard let url = URL(string: "https://picsum.photos/200") else {return}
let (data, _ ) = try await URLSession.shared.data(from: url, delegate: nil)
self.image = UIImage(data: data)
} catch {
print(error.localizedDescription)
}
}
func fetchImage2() async {
do {
guard let url = URL(string: "https://picsum.photos/200") else {return}
let (data, _ ) = try await URLSession.shared.data(from: url, delegate: nil)
self.image2 = UIImage(data: data)
} catch {
print(error.localizedDescription)
}
}
}
struct TaskBootcamp: View {
@StateObject private var viewModel = TaskBootcampViewModel()
var body: some View {
VStack(spacing : 40){
if let image = viewModel.image {
Image(uiImage: image)
.resizable()
.scaledToFit()
.frame(width: 200, height: 200)
}
if let image = viewModel.image2 {
Image(uiImage: image)
.resizable()
.scaledToFit()
.frame(width: 200, height: 200)
}
}
.onAppear{
Task {
await viewModel.fetchImage()
}
Task{
await viewModel.fetchImage2()
}
}
}
}
struct TaskBootcamp_Previews: PreviewProvider {
static var previews: some View {
TaskBootcamp()
}
}