티스토리 뷰
[1] AsyncSequence
- iterator 를 통해 elements 에 접근하는 Sequence 와 동일한 개념. 대신 asynchronous 하게 element 를 접근한다는 점이 Sequence 와 다름.
영어가 더 깔끔한 듯.. ?
‘AsyncSequence is a protocol which resembles Sequence and allows you to iterate over a sequence of values asynchronously.’
- iterator 의 next() 를 호출하거나 for await loops 를 사용해서 elements 에 접근할 수 있음
- AsyncSequence 프로토콜의 requirement 를 간략히 적어보자면 다음과 같음
protocol AsyncSequence {
...
associatedtype AsyncIterator : AsyncIteratorProtocol
func makeAsyncIterator() -> Self.AsyncIterator
}
protocol AsyncIteratorProtocol {
...
func next() async throws -> Self.Element?
}
- My Own AsyncSequence 를 만든 예시 (출처: Modern Concurrency in Swift)
struct Typewriter: AsyncSequence {
typealias Element = String
let phrase: String
func makeAsyncIterator() -> TypewriterIterator {
return TypewriterIterator(phrase)
}
}
struct TypewriterIterator: AsyncIteratorProtocol {
typealias Element = String
let phrase: String
var index: String.Index
init(_ phrase: String) {
self.phrase = phrase
self.index = phrase.startIndex
}
// next() returns nil to signify the end of the sequence.
mutating func next() async throws -> String? {
guard index < phrase.endIndex else {
return nil
}
try await Task.sleep(nanoseconds: 1_000_000_000)
defer {
index = phrase.index(after: index)
}
return String(phrase[phrase.startIndex...index])
}
}
for try await item in Typewriter(phrase: "Hello, world!") {
print(item)
}
/*
H
He
Hel
Hell
Hello
Hello,
Hello,
Hello, w
Hello, wo
Hello, wor
Hello, worl
Hello, world
Hello, world!
*/
[2] AsyncStream
AsyncStream 은 AsyncSequence 를 더 쉽고 빠르게 만들기 위한 방법. (iterator 별도로 안만들어도 됨)
AsyncStream 은 AsyncSequence 를 채택하고 있음.
이것도 영어가 더 깔끔한 듯..
'AsyncStream conforms to AsyncSequence, providing a convenient way to create an asynchronous sequence
without manually implementing an asynchronous iterator'
이 이니셜라이저를 통해 Continuation-Based Stream 을 만들 수 있음.
let counter = AsyncStream<String> { continuation in
}
[3] AsyncStream.Continuation
- CheckedContinuation 과 다른 타입임!
- yield (Producing Elements) / finish (Finishing the Stream) 메소드를 제공함.
✅ Task.yield 랑 헷갈리면 안됨!!
Task.yield 는 현재 Task의 실행을 자발적으로 일시 중단하고, 다른 대기 중인 작업들에게 실행 기회를 주는 함수.
하지만 AsyncStream.Continuation.yield 는 일시 중단이 아니라 값을 방출하는 함수임.
- My Own Timer 만드는 예제 (출처: Modern Concurrency in Swift)
let counter = AsyncStream<String> { continuation in
var countdown = 3
Timer.scheduledTimer(
withTimeInterval: 1.0,
repeats: true
) { timer in
guard countdown > 0 else {
timer.invalidate() // stop the timer
continuation.yield("🎉 complete") // yield a final value
continuation.finish() // complete the sequence
return
}
continuation.yield("\(countdown)..")
countdown -= 1
}
}
for await countdownMessages in counter {
print(countdownMessages)
}
/*
3..
2..
1..
🎉 complete
*/
참고로 이 두 줄을 아래 한줄로 바꿔도 무방.
[AS IS]
continuation.yield("🎉 complete") // yield a final value
continuation.finish() // complete the sequence
[TO BE]
continuation.yield(with: .success("🎉 complete")) // shortcut. yield a final value + complete the sequence
[4] 기존 기능에 AsyncStream 통합하기
- notification center 을 async stream 을 사용하여 확장한 예제. notifications 를 async sequeuce 를 형태로 받을 수 있도록.
(출처: Modern Concurrency in Swift)
extension NotificationCenter {
func notifications(for name: Notification.Name) -> AsyncStream<Notification> {
AsyncStream<Notification> { continuation in
NotificationCenter.default.addObserver(
forName: name,
object: nil,
queue: nil
) { notification in
continuation.yield(notification)
}
}
}
}
for await _ in NotificationCenter.default.notifications(for: UIApplication.willResignActiveNotification) {
// do something
}
for await _ in NotificationCenter.default.notifications(for: UIApplication.didBecomeActiveNotification) {
// do something
}
이미 애플에서 Receiving Notifications as an Asynchronous Sequence 제공해서
별도 구현없이 이렇게 쓸 수 있음! (예제로 보여주려고 책 저자분께서 첨부한 것. 혼동 X)
for await _ in NotificationCenter.default.notifications(named: UIApplication.didBecomeActiveNotification) {
// do something
}
'🍏 > Swift' 카테고리의 다른 글
[Swift] Noncopyable (~Copyable) (3) | 2024.10.26 |
---|---|
[Swift] Typed throws (0) | 2024.10.13 |
[Swift] @TaskLocal (0) | 2024.08.23 |
[Swift] @dynamicCallable 유용한 예제 모음 (4) | 2024.03.16 |
[Swift] KeyPath 유용한 예제 모음 (32) | 2023.10.21 |
- Total
- Today
- Yesterday
- Flutter Spacer
- Python Type Hint
- Dart Factory
- Django FCM
- flutter build mode
- DRF APIException
- flutter deep link
- Flutter Clipboard
- Django Heroku Scheduler
- ipad multitasking
- flutter dynamic link
- Watch App for iOS App vs Watch App
- drf custom error
- 장고 URL querystring
- cocoapod
- 구글 Geocoding API
- github actions
- 장고 Custom Management Command
- Flutter Text Gradient
- PencilKit
- 플러터 싱글톤
- 플러터 얼럿
- Flutter getter setter
- Flutter 로딩
- SerializerMethodField
- METAL
- ribs
- Django Firebase Cloud Messaging
- flutter 앱 출시
- Sketch 누끼
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 | 31 |