LoginSignup
12
11

More than 1 year has passed since last update.

【SwiftUI】.onAppearと.taskの違い

Last updated at Posted at 2022-08-28

はじめに

SwiftUIでは、ある特定のViewが表示された場合に処理を実行させたい場合
.onAppearもしくは.taskを使うのが良さそうだと思いましたが、2つの違いがよく分からなかったので調べてみました。

環境

Xcode 13.4.1

内容

.onAppear

Viewが表示される前に実行するアクションを追加

func onAppear(perform action: (() -> Void)? = nil) -> some View

SwiftUI がこのメソッドを呼び出す正確な瞬間は、適用する特定のビューの種類に依存するが、アクションクロージャーは最初のレンダリングフレームが表示される前に完了する

.task

Viewが表示される前に実行する非同期タスクを追加

func task(
    priority: TaskPriority = .userInitiated,
    _ action: @escaping () async -> Void
) -> some View

.taskでViewのライフタイムと一致する非同期タスクを実行できる。Viewを削除するか、Viewの ID が変更される前にタスクが終了しない場合、SwiftUI はタスクをキャンセルする

非同期呼び出しが完了するのを待つか、AsyncSequenceインスタンスの値で待つために、タスク内でawaitキーワードを使用する


let url = URL(string: "https://example.com")!
@State private var message = "Loading..."

var body: some View {
    Text(message)
        .task {
            do {
                var receivedLines = [String]()
                for try await line in url.lines {
                    receivedLines.append(line)
                    message = "Received \(receivedLines.count) lines"
                }
            } catch {
                message = "Failed to load"
            }
        }
}

.onAppear.taskの違い

.onAppearの中には非同期処理が書けない

スクリーンショット 2022-08-28 11.18.58.png
※ 非同期関数型 '() async -> Void' から同期関数型 '() -> Void' への変換は無効です。

ただしTaskを追加することで.onAppearでも非同期処理が使えますが、
.taskを使った場合は、例えばViewが非表示となった時に実行されている処理が自動的にキャンセルされるようなので、この違いは残るようですね

        Text(message)
            .onAppear {
                Task {
                    do {
                        var receivedLines = [String]()
                        for try await line in url.lines {
                            receivedLines.append(line)
                            message = "Received \(receivedLines.count) lines"
                        }
                    } catch {
                        message = "Failed to load"
                    }
                }
            }

おわりに

.taskを使う場合で意図せずタスクがキャンセルされることはあるのだろうか。。。その場合は.onAppear+Taskを使うメリットがあるのかも?🤔(このあたりはまだ理解できていない...)
Taskについても深堀しようと書きながら調べてみましたが、さらっとまとめられる内容ではなく諦めました。。。

参考

12
11
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
11