티스토리 뷰
과거에 Continuations 를 이용해서 짰던 코드를 보는데 헷갈렸다.. @)@
리마인드가 필요하군
우선 요 목차(?)가 머릿 속에 있어야한다.
[1] 용어 기억
가끔 용어도 잘 생각이 안날 때가 있다,,
[ Continuation ]
비동기 코드를 래핑해서 연속(continuation)을 만든다! 라고 기억하자
문서에서는 이렇게 표현한다.
To create a continuation in asynchronous code,
call the withUnsafeContinuation(function:_:) or withUnsafeThrowingContinuation(function:_:) function.
[ CheckedContinuation vs UnsafeContinuation ]
잘 까먹는 주요원인이다.
checked / unchecked 이던가.. safe / unsafe 이던가.. 하면 더 쉽게 기억할텐데 따흑,,
CheckedContinuation 은 resume이 빠졌거나 여러번 불리는 지를 런타임때 체크하고
UnsafeContinuation 은 체크안한다 (오버헤드를 피하기 위해)
CheckedContinuation performs runtime checks for missing or multiple resume operations.
UnsafeContinuation avoids enforcing these invariants at runtime because it aims to be a low-overhead mechanism for interfacing Swift tasks with event loops, delegate methods, callbacks, and other non-async scheduling mechanisms
이 글에서 자세한 실험을 볼 수 있다.
[2] 사용예시
보통 두가지 경우에 사용한다.
1) completion -> async/await
completion handler 를 파라미터로 받는 function을 래핑해서 async function 을 만들고 싶을 때 사용한다.
여기 예제 잘 설명되어있음
http://minsone.github.io/swift-concurrency-continuation
2) delegate -> async/await
delegate 패턴 대신 async function 을 만들고 싶을때 사용한다.
예를들어
StoreKit 1 의 대부분은 delegate 패턴인데
ProductFetcher, ReceiptLoader 등 각각 객체를 만들고 asyn/await 를 사용할 수 있게 해주면 코드가 훨씬 간결해진다.
fetchAvailableProducts 을 asyn function으로 만드려면
request 가 성공, 실패할때 불리는 delegate function 내에서 resume이 호출되게 해주면 된다.
class IAPProductsFetcher: NSObject, SKProductsRequestDelegate {
private var productsRequest: SKProductsRequest?
private var productsRequestDoneAction: (([SKProduct]) -> Void)?
private let productIds: [String]
init(productIds: [String] = IAPProducts.identifiers) {
self.productIds = productIds
}
func fetchAvailableProducts() async -> [SKProduct] {
return await withCheckedContinuation { continuation in
self.productsRequestDoneAction = {
continuation.resume(returning: $0)
}
self.fetchProducts(matchingIdentifiers: self.productIds)
}
}
private func fetchProducts(matchingIdentifiers identifiers: [String]) {
let productIdentifiers = Set(identifiers)
let productsRequest = SKProductsRequest(productIdentifiers: productIdentifiers)
productsRequest.delegate = self
self.productsRequest = productsRequest
productsRequest.start()
}
// MARK: - SKProductsRequestDelegate
func productsRequest(_ request: SKProductsRequest, didReceive response: SKProductsResponse) {
let availableProducts = response.products
self.productsRequestDoneAction?(availableProducts)
self.productsRequestDoneAction = nil
}
func request(_ request: SKRequest, didFailWithError error: Error) {
self.productsRequestDoneAction?([])
self.productsRequestDoneAction = nil
}
}
'🍏 > Swift' 카테고리의 다른 글
[Swift] KeyPath 유용한 예제 모음 (32) | 2023.10.21 |
---|---|
[Swift] RandomAccessCollection / BidirectionalCollection 의 Time Complexity (0) | 2023.09.23 |
[Swift] self in a closure in a closure (0) | 2023.07.11 |
[Swift Collections] Heap (0) | 2023.05.20 |
[Swift] Dictionary 의 subscript 3개 / KeyValuePairs (0) | 2023.04.29 |
- Total
- Today
- Yesterday
- DRF APIException
- ipad multitasking
- Flutter Spacer
- flutter build mode
- drf custom error
- Flutter 로딩
- flutter 앱 출시
- cocoapod
- Flutter Clipboard
- Flutter getter setter
- Django FCM
- 장고 URL querystring
- Flutter Text Gradient
- Python Type Hint
- 플러터 얼럿
- 플러터 싱글톤
- github actions
- Dart Factory
- Watch App for iOS App vs Watch App
- Sketch 누끼
- PencilKit
- flutter dynamic link
- SerializerMethodField
- 구글 Geocoding API
- ribs
- Django Heroku Scheduler
- 장고 Custom Management Command
- flutter deep link
- Django Firebase Cloud Messaging
- METAL
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |