SwiftUIのViewのメソッドの.task()
の中の処理はViewが表示されると非同期で実行されて、もしViewが非表示になるまでTaskが実行中ならそのTaskは自動でcancelされる。
もし自動でcancelされないようにしたい場合は.onAppear()
の中でTask
を直接に生成する。
サンプルコードのログをみるとTaskViewを表示してRequestが完了する前にビューを非表示にすると.task()
からのTask
はcancelされるが.onAppear()
からのTask
はcancelされないことがわかる。
struct TaskView: View {
var body: some View {
Circle()
.task {
await fetch(title: "from .task: ")
}
.onAppear {
print("onAppear")
Task {
await fetch(title: "from onAppear::Task: ")
}
}
.onDisappear {
print("onDisappear")
}
}
func fetch(title: String) async {
print("\(title) Started")
let request = URLRequest(url: URL(string: "https://hmhv.info")!, cachePolicy: .reloadIgnoringLocalAndRemoteCacheData)
do {
let (_, response) = try await URLSession.shared.data(for: request)
print("\(title) \((response as! HTTPURLResponse).statusCode)")
} catch {
print("\(title) Error : \(error.localizedDescription)")
}
print("\(title) Finished")
}
}
onAppear
from .task: Started
from onAppear::Task: Started
onDisappear
from .task: Error : cancelled
from .task: Finished
from onAppear::Task: 200
from onAppear::Task: Finished