SwiftUIでいこう! - 非同期処理を考える。
JavaScriptの非同期処理を見てきましたがSwiftではどうでしょう。Swiftでもasync,awaitを使って非同期処理を行います。
同じようにasyncをつけた関数の中にawaitを着けて関数を指定します。
実際の使用例として上記参考サイトで例示してあります。
struct ContentView: View {
@State var text = "Default"
var body: some View {
VStack {
Text(self.text)
Button("Wait"){
self.text = "Waiting"
Task{
self.text = await waitFunc()
print("waitFunc後に実行")
}
print("waitFuncと並列実行")
}
}
}
func waitFunc() async -> String {
sleep(5)
return "Finish"
}
}
これを実行すると確かにボタン押せばうまく時間をおってコンソールに出力されます。
下の方にコンソールの結果が出てきています。
同じことをDispatchQueueのコードも紹介されていて、実行すると同じように結果が出ることが確認できます。
Swiftの場合には安全に非同期処理をするために"Actor"というものを作っています。
SwiftUIで書く場合には
struct ContentView: View {
@State var text = "Default"
var body: some View {
VStack {
Text(self.text)
Button("Wait"){
self.text = "Waiting"
Task{
let asyncClass = AsyncClass()
self.text = await asyncClass.waitFunc()
print("waitFunc後に実行")
}
print("waitFuncと並列実行")
}
}
}
}
class AsyncClass{
func waitFunc() async -> String {
sleep(5)
return "Finish"
}
}
という感じでクラスを別立てで作ってそれを本体の"body"の中で使っていきます。
Task
上記サイトを参考に
func fetchHogeAPI() async throws -> Void {
try await Task.sleep(nanoseconds: 1 * 1000 * 1000 * 1000)
return ()
}
do {
try await fetchHogeAPI()
} catch {
print(error)
}
エラーが出ます。Taskを使います。
Task {
do {
try await fetchHogeAPI()
} catch {
print(error)
}
print("call2")
}
これでエラーが消えます。
"Task"とするとメインスレッドで実行されるがそれ以外で使いたいという場合は
を使う。
async let
並列で処理したい時に使うことができます。
基本の書き方は
async letで定義するところではawaitキーワードは不要で、その値を実際に使いたい時にawaitを記述します。
Task Group
Task Group の生成にはwithTaskGroupと withThrowingTaskGroup があります。
async letとTask Groupの使い分け
上記以外でもいろんなところ、いろんな視点からまとめられていますのでご紹介。自分でわかりやすいところ、ポイントを掴んでいけば良いかなと思います。