티스토리 뷰
iOS Swift Concurrency, async await 방식의 이점과 사용 간에 생길 수 있는 고민
iOS13 부터 활용 가능한 async await, actor 등의 개념을 잘 활용하면 data racing 문제를 해결하고, 많은 thread의 생성을 야기할 수 있는 context switching을 최소화 할 수 있습니다. 또한, callback closure의 중첩으로 인한 콜벡지옥 등으로 인한 나쁜 가독성을 개선할 수도 있습니다.
async await 을 사용할 때에는 일반적으로 함수 반환 타입 앞에 async, async throws를 사용하고, 호출할때에는 Task { ... }, .task { ... } 블럭 내에 await, try await 키워드와 함께 호출하여 사용하게 되는데요.
많은 장점을 갖고 있는 이 async await을 이곳 저곳 모두에 적용하여 사용하고 싶을 수 있겠지만, 적용을 하다보면 고민에 빠지게 될 때가 있을 거에요.
escaping closure callback 인자를 가진 레거시 코드, 근데 레거시한 코드나 third party library 코드 등을 사용하게 되면 해당 메서드 자체를 async await method로 뜯어 고치는 것이 힘든데요. 이 경우에는 async await 방식으로 적용할 방법이 없을까요?
이런 메서드를 브릿징해서 외부에서 async await 하게 사용할 수 있는 방법이 있습니다. 바로 withCheckedThrowingContinuation, withCheckedContinuation입니다. 개발자 문서를 보면서 시작해보겠습니다.
withCheckedThrowingContinuation, withCheckedContinuation 개발자 문서 개요
꽤나 긴 이름을 갖고 있는 이 기능들에 대해서 보겠습니다. 먼저, 해당 기능은 여타 async await 기능들 처럼 iOS13+에서 사용이 가능합니다. 현재의 작업을 일시중단하고, 현재 작업에 대한 closure를 호출한다고 합니다. 이때 closure에서는 특정 값을 반환하거나, error를 던질 수도 있습니다.
error를 throwing하려면, withCheckedThrowingContinuation을, error를 throwing할 필요가 없다면, throwing 키워드가 없는 withCheckedThrowingContinuation을 사용할 수 있습니다.
그리고 withCheckedContinuation, withCheckedThrowingContinuation 을 사용하게 되면 각각 그 앞에 await, try await을 붙혀서 사용하게 됩니다.
해당 기능의 선언 형태인데요. 이처럼 async throws로 선언되어있는 기능 이기때문에 그 앞에 await, try await이 붙을 수밖에 없겠습니다. 그리고 클로져 내에서 어떠한 값을 반환하거나 Error를 던질때 resume(returning:), resume(throwing:)을 사용할 수 있습니다.
withCheckedThrowingContinuation, withCheckedContinuation을 활용한
method 브릿징 및 사용 예시
가령, URLSession을 통해 dataTask 메서드를 사용할 수 있는데요. iOS15+ 에서만 async throws method를 기본 제공하고 있습니다. withCheckedThrowingContinuation을 활용하면 iOS13+ 에서도 iOS15+에서만 제공하는 메서드와 유사한 메서드를 구현 할 수 있습니다.
withCheckedThrowingContinuation의 body 블럭 내에서는 CheckedContinuation 구조체 타입의 continuation을 사용할 수 있는데, 해당 구조체 인스턴스의 resume 메서드를 통해서 값을 반환하거나, 에러를 던질 수 있어요.
주의할 점은, 클로져 내에서는 resume이 딱 한번 호출되도록 해야 한다고 개발자 문서에 명시되어 있습니다. (CheckedContinuation 개발자 문서 참고)
위에서 구현한 예제 메서드를 실제로 사용하는 모습입니다. escaping closure callback 인자를 가진 메서드를 withCheckedThrowingContinuation으로 wrapping해서 외부에서 async await 하게 사용이 가능한 것을 볼 수 있습니다.
이 외에도 Google Kakao API 등 다양한 외부 라이브러리를 사용할때 원한다면 언제든지 withCheckedThrowingContinuation, withCheckedContinuation 등을 사용해서 브릿징을 하고, 외부에서 async await 하게 기능을 구현할 수 있습니다.
오늘은 iOS개발간에 기존에 많이 사용되던 escaping closure callback 인자를 가진 외부 라이브러리, 레거시 기능을 async await 한 방식으로 외부에서 사용 가능하도록 브릿징 하는 방법을 알아봤습니다.
withCheckedThrowingContinuation, withCheckedContinuation 사용 방법에 대해서 의견 있으시면 언제든 댓글 주시면 감사하겠습니다. 즐거운 하루 되세요. 🤗
'iOS 개발 > iOS 개발 팁' 카테고리의 다른 글
swift, protocol과 associatedtype, 연관타입 제약 사용방법 (0) | 2023.03.05 |
---|---|
iOS Protocol, OpaqueType 반환타입 사용 시 차이점 (0) | 2023.01.29 |
iOS TDD, UnitTest UITest Target 생성 및 테스트코드 작성방법 (0) | 2023.01.24 |
Structured Concurrency, async let, TCA API 요청 간 적용방법 (0) | 2022.10.30 |
Swift KVC, KeyPath, WritableKeyPath 읽기 쓰기 사용방법 (0) | 2022.10.23 |
- Total
- Today
- Yesterday
- 김프매매
- swift알고리즘
- ios
- uikit
- 개발자문서
- swift reduce
- 자연어처리
- publisher
- 백준알고리즘
- swift string
- 스위프트
- swift 기초
- createML
- swift문제
- 부스트코스
- 알고리즘
- 컬렉션
- SwiftUI
- swift언어
- Protocol
- 백준swift
- Swift 알고리즘
- 프로그래머스swift
- swift
- 프로토콜
- 프로그래머스
- 알고리즘문제
- Collection
- swift 문자열
- CoreML
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |