본문 바로가기

IOS

Swift - async await

Swift 에는 여러 가지의 비동기 처리 방법이 있는데

대표적으로는 DispatchQueue, CompletionHandler, RxSwift, Combine 등이 있다.

지난 WWDC 2021 에서 Async Await 를 발표하였다 기존까지 RxSwift, Combine 이용하고 있어서 늦게 학습 하였지만

상당히 축소되고 알아보기도 쉬워 끄적끄적 해본다..


Async Await 를 본격적으로 알아보기 전에, 현재 어떻게 비동기 처리를 하고 있었는지 알아보도록 하자.

 

func processImageData1(completionBlock: (_ result: Image) -> Void) {
    loadWebResource("dataprofile.txt") { dataResource in
        loadWebResource("imagedata.dat") { imageResource in
            decodeImage(dataResource, imageResource) { imageTmp in
                dewarpAndCleanupImage(imageTmp) { imageResult in
                    completionBlock(imageResult)
                }
            }
        }
    }
}

processImageData1 { image in
    display(image)
}

 

Result 타입이 신규로 나와도 다음과 같이 소스가 길고 복잡하게 나올수 밖에 없다.

 

func processImageData2c(completionBlock: (Result<Image, Error>) -> Void) {
    loadWebResource("dataprofile.txt") { dataResourceResult in
        switch dataResourceResult {
        case .success(let dataResource):
            loadWebResource("imagedata.dat") { imageResourceResult in
                switch imageResourceResult {
                case .success(let imageResource):
                    decodeImage(dataResource, imageResource) { imageTmpResult in
                        switch imageTmpResult {
                        case .success(let imageTmp):
                            dewarpAndCleanupImage(imageTmp) { imageResult in
                                completionBlock(imageResult)
                            }
                        case .failure(let error):
                            completionBlock(.failure(error))
                        }
                    }
                case .failure(let error):
                    completionBlock(.failure(error))
                }
            }
        case .failure(let error):
            completionBlock(.failure(error))
        }
    }
}

processImageData2c { result in
    switch result {
    case .success(let image):
        display(image)
    case .failure(let error):
        display("No image today", error)
    }
}

 

그만큼, 에러 핸들링이 어렵고 개발자가 일일히 로직에 에러 핸들링에 대한 처리를 해줘야한다. 뭐 콜백 지옥이라고도 한다.

 

자..! 이제 적용 해보자..


위에있는 소스를 async await 를 적용하면 다음과 같이 나온다. 

 

func loadWebResource(_ path: String) async throws -> Resource
func decodeImage(_ r1: Resource, _ r2: Resource) async throws -> Image
func dewarpAndCleanupImage(_ i : Image) async throws -> Image

func processImageData() async throws -> Image {
  let dataResource  = try await loadWebResource("dataprofile.txt")
  let imageResource = try await loadWebResource("imagedata.dat")
  let imageTmp      = try await decodeImage(dataResource, imageResource)
  let imageResult   = try await dewarpAndCleanupImage(imageTmp)
  return imageResult
}

 

이렇게만 보면 어려우니까 한줄씩 끊어서 자세하게 보자.

 

함수 선언부 뒤에 async 가 나온다면 비동기를 뜻한다. 키워드가 섞여서는 안된다 (throws async)(X)

신기하게 호출은 try await 로한다..

 

func loadWebResource(_ path: String) async throws -> Resource

 

async 호출을 하기위한 키워드는 앞에 await 를 붙여줘야합니다.

 

let dataResource  = try await loadWebResource("dataprofile.txt")

 

View 

VStack {
	View....
}.task {
	await 키워드 이용 function 호출
}

ViewModel

func example()  {
    Task {
       await 키워드 이용 function 호출
    }
}

Task

비동기 함수를 호출할때 Task 라는 로직 안에 이용해야 합니다. 약간 Android 상에 있는 코루틴과 비슷합니다.

해당 Task 에 속해있는 블록은 백그라운드 영역에서 돕니다

Task 는 옵션을 통해 우선순위를 줄수 있습니다. (high, default, low) 등등....

ex) Task(priority: .high)

 


마치며

이미 많은 능력자 분들의 블로그 내용도 있지만 내 머릿속의 쏙쏙 넣기위해 작성했는데

작성하면서도 재미있는 기술이 있어 현재 진행중인 Combine 프로젝트에 적용하고 싶은 욕심이 생깁니다.

다음 내용은 Combine -> async await 적용기 적어보도록 하겠슴다

* 아직 내용이 많이 부족하여 공부하면서 계속 수정 하겠습니다!

 

참고 : https://github.com/apple/swift-evolution/blob/main/proposals/0296-async-await.md

 

GitHub - apple/swift-evolution: This maintains proposals for changes and user-visible enhancements to the Swift Programming Lang

This maintains proposals for changes and user-visible enhancements to the Swift Programming Language. - GitHub - apple/swift-evolution: This maintains proposals for changes and user-visible enhance...

github.com

 

 

'IOS' 카테고리의 다른 글

iOS - 프로젝트에 SPM 을 달아보자  (0) 2023.02.19
Xcode - Google Sheet 에서 다국어 내용 가져오기  (0) 2023.01.23
SwiftUI - List Hide Indicator  (0) 2022.10.23
SwiftUI - TextView Attribute  (0) 2022.06.01
Swift - Snapkit  (0) 2022.04.10