Jaebi의 Binary는 호남선

SwiftUI - .onAppear() vs .task() 본문

Swift

SwiftUI - .onAppear() vs .task()

jaebijae 2024. 7. 23. 19:57

목차

  • 둘다 뷰가 화면에 나타날 때 작업을 수행하는데 사용되는 view modifiers 지만 용도가 다름

.onAppear()

  • iOS 13.0+
  • 주로 뷰가 화면에 처음 나타날 때 작업을 수행하거나 프로세스를 시작할때 사용
  • 내부 코드는 뷰가 처음 보여질때와 다시 나타날 때마다 (ex. navigating back) 실행
  • `.onAppear()` 내부에 `Task`를 넣어 비동기 작업도 수행 가능 (`.task()`와 동일한 기능)

.task()

  • iOS 15.0+
  • 뷰가 나타날때 비동기 작업을 수행하도록 설계되어 있음
  • 내부의 코드는 서버에서 데이터 가져올때, 데이터베이스 읽기, 또는 백그라운드 task 수행과 같은 비동기 작업을 수행
  • SwiftUI는 뷰가 나타날 때 작업이 한 번만 수행되도록 보장, 뷰 업데이트로 인한 여러 실행을 방지
  • SwiftUI가 작업의 lifecycle을 자동으로 관리하여 뷰가 화면에 없으면 (ex. navigation) 취소되도록 함
  • `.task()`는 값이 변경될때 task를 취소하고 다시 시작할 수 있게 하는 id parameter사용 가능
    • `.onAppear()`에서 하려면 `@State`와 `@Binding`으로 업데이트를 해야함
       
struct ContentView: View {
    @State var text: String = "Loading..."
    @State var category: String = "Swift"
    func getTextAfterFiveSeconds(category: String) async -> String {
        do {
            try await Task.sleep(for: .seconds(5))
        } catch is CancellationError {
            print("task: \(category) cancelled!")
        } catch {
            print("task: \(category) error!")
        }
        return "Hello, \(category)!"
    }
    var body: some View {
        VStack {
            Text(text)
                // id parameter에 category를 넣어 해당 값이 바뀔때마다 기존 task cancel및 task 실행
                .task(id: category) {
                    print("task: \(category) started!")
                    let result = await getTextAfterFiveSeconds(category: category)
                    print("task: \(category) ended!")
                    text = result
                }
            Picker("Select a category", selection: $category) {
                Text("Swift").tag("Swift")
                Text("iOS").tag("iOS")
                Text("macOS").tag("macOS")
            }
            .pickerStyle(.segmented)
        }
    }
}
  • `.task()`는 task의 우선순위를 지정할 수 있는 priority parameter사용 가능
    • 해당 기능을 사용하여 backround task보다 사용자가 시작한 task를 우선으로 할 수 있게 가능
    • `.onAppear()`에서 하려면 `Task`, `DispatchQueue` 또는 `OperationQueue`를 사용해야 함
    • TaskPriority: task가 어떻게 생성되었는지에 따라 달라짐 → 다른 task에서 생성되었으면 부모 task의 priority, main thread에서 직접 생성되었으면 `.userInitiated`, 둘다 아니면 nil이나 thread의 priority
      • `.high`: `.userInitiated`과 동의어, user가 직접 시작하고 actively 기다리고 있는 작업
      • `.medium`: user가 active하지 않게 기다리고 있는 작업
      • `.low`: `.utility`와 동의어, 긴 작업이라 progress bar가 보여야 하는 작업에 적합 (copying files, importing data)
      • `.background`: user가 볼 수 없는 작업들 (building a search index 등)

.task() vs .onAppear() 사용 정리

  • `.onAppear()` 사용:
    • 뷰가 나타날 때마다 간단한 작업이나 업데이트를 수행
    • 작업이 동기식이며 async/await 작업을 포함하지 않음
  • `.task()` 사용:
    • 뷰가 나타날 때마다 비동기 작업 (ex. network requests, database queries)을 수행
    • View에 여러번 업데이트가 있더라도 View가 나타날때 한번만 작업이 수행되어야 할때 사용

Reference

 

onAppear(perform:) | Apple Developer Documentation

Adds an action to perform before this view appears.

developer.apple.com

 

 

task(priority:_:) | Apple Developer Documentation

Adds an asynchronous task to perform before this view appears.

developer.apple.com

 

 

.task() vs .onAppear()

In SwiftUI, .task() and .onAppear() are both view modifiers used to perform actions when a view appears on the screen, but ….

medium.com

'Swift' 카테고리의 다른 글

Swift 개발시 유용한 링크  (0) 2024.08.05
UIKit - 기본  (0) 2024.08.05
SwiftUI - ViewModifier  (1) 2024.07.23
SwiftUI - Navigation  (1) 2024.07.23
AppDelegate & SceneDelegate  (0) 2024.07.21