apple/Docs, iOS, Swift

Swift withTaskCancellationHandler

lgvv 2024. 8. 17. 22:45

Swift withTaskCancellationHandler

 

withTaskCancellationHandler란?

  • Task가 cancel 되었을 때 동작을 정의할 수 있음.
    • throw 던지면 catch에서 잡는다고 생각하면 편함.
  • (중요) Task가 cancel 된다고 작업이 즉시 중단되는건 아님. 작업 내에서 취소 상태를 확인하고 이에 따른 핸들링이 필요.

 

예제 코드 및 영상

샘플 예제 설명

  • performTask(): 1부터 10까지 1초마다 반복
  • Task가 cancel 되는 조건
    • 버튼을 클릭해 다음 뷰로 이동했을 때
    • 3초가 지났을 때
  • (참고) task modifier는 (onAppear + Task)와 동일
    • (주의) task에서 해당 코드 형태로 작성할 시 뷰가 사라지더라도 @State로 선언되 Task는 사라지지 않아서 계속해서 타이머가 진행되는 문제

결과

  • Task가 취소될 때 즉시 for문이 전부 수행
  • 단 Task.isCancelled가 true로 바뀌어있음.
  • 내부적으로 핸들링이 필요.

 

 

import SwiftUI

struct WithTaskCancellationHandlerExampleView: View {
    
    @State private var task: Task<Void, Never>?
    
    var body: some View {
        NavigationView {
            NavigationLink {
                Text("Hello World")
            } label: {
                Text("버튼")
                    .onDisappear {
                        print("onDisappear")
                        task?.cancel()
                    }
            }
        }
        .task {
            print("task: onAppear")
            self.task = Task {
                await withTaskCancellationHandler {
                    await performTask()
                } onCancel: {
                    print("onCancel")
                }
            }
            
            // 3초 후에 작업 취소
            DispatchQueue.main.asyncAfter(deadline: .now() + 3) {
                task?.cancel()
            }
        }
        
    }
    
    func performTask() async {
        for i in 1...10 {
            print("Working on step \(i)... | \(Task.isCancelled)")
            try? await Task.sleep(nanoseconds: 1_000_000_000) // 1초 대기
        }
    }
}

#Preview {
    WithTaskCancellationHandlerExampleView()
}

 

영상

 

Task가 onDisappear에 의해 취소되는 경우
Task가 3초 이후에 취소되는 경우

 

 

 

'apple > Docs, iOS, Swift' 카테고리의 다른 글

CloudKit 정리 코드 예제 #3  (0) 2024.08.18
iOS TipKit 사용 예제 정리  (2) 2024.08.18
Swift AsyncStream, AsyncThrowingStream 정리  (2) 2024.08.16
Swift nonmuating, mutating  (0) 2024.08.14
Swift Entry macro (@Entry)  (0) 2024.08.07