AsyncSequence 예시 코드
@main
struct QuakesTool {
static func main() async throws {
let endpointURL = URL(string: "https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_month.csv")!
// skip the header line and iterate each one
// to extract the magnitude, time, latitude and longitude
for try await event in endpointURL.lines.dropFirst() {
let values = event.split(separator: ",")
let time = values[0]
let latitude = values[1]
let longitude = values[2]
let magnitude = values[4]
print("Magnitude \(magnitude) on \(time) at \(latitude) \(longitude)")
}
}
}
Iterating Sequence
for quake in quakes {
if quake.magnitude > 3 {
displaySignificantEarthquake(quake)
}
}
- 우리가 흔하게 작성하는 sequence의 예시
AsyncSequence
1. async가 아닌 sequence와 유사하다.
2. throw 가능
3. 작업을 끝까지 완료하거나 오류로 종료 가능
4. map, allSatisfy등 다양한 오퍼레이터 사용 가능
How the compiler handles iteration
var iterator = quakes.makeIterator()
while let quake = iterator.next() {
if quake.magnitude > 3 {
displaySignificantEarthquake(quake)
}
}
- 컴파일러가 앞선 예시의 반복문을 처리하는 방식은 위와 같다.
Iterating an asyncSequence
for await quake in quakes {
if quake.magnitude > 3 {
displaySignificantEarthquake(quake)
}
}
- asyncSequence에서 반복문을 작성하는 방법은 위와 같다.
- break, continue 구문도 사용 가능
- throw도 가능하다.
do { for try await quake in quakeDownload { ... } } catch { ... }
How the compiler handles asynchronous iteration
var iterator = quakes.makeAsyncIterator()
while let quake = await iterator.next() {
if quake.magnitude > 3 {
displaySignificantEarthquake(quake)
}
}
- 컴파일러가 asyncSequence를 처리하는 방식
Concurrently iterating inside an async task
let iteration1 = Task {
for await quake in quakes {
...
}
}
let iteration2 = Task {
do {
for try await quake in quakeDownload {
...
}
} catch {
...
}
}
//... later on
iteration1.cancel()
iteration2.cancel()
- Task 블록 안에 반복문을 넣어 동시성을 추가 할 수 있다.
- cancel()을 통해 최소도 가능하다.
Reading bytes from a URLSession
let (bytes, response) = try await URLSession.shared.bytes(from: url)
guard let httpResponse = response as? HTTPURLResponse,
httpResponse.statusCode == 200 /* OK */
else {
throw MyNetworkingError.invalidServerResponse
}
for try await byte in bytes {
...
}
Notifications
let center = NotificationCenter.default
let notification = await center.notifications(named: .NSPersistentStoreRemoteChange).first {
$0.userInfo[NSStoreUUIDKey] == storeUUID
}
Using an AsyncStream
class QuakeMonitor {
var quakeHandler: (Quake) -> Void
func startMonitoring()
func stopMonitoring()
}
let quakes = AsyncStream(Quake.self) { continuation in
let monitor = QuakeMonitor()
monitor.quakeHandler = { quake in
continuation.yield(quake)
}
continuation.onTermination = { @Sendable _ in
monitor.stopMonitoring()
}
monitor.startMonitoring()
}
let significantQuakes = quakes.filter { quake in
quake.magnitude > 3
}
for await quake in significantQuakes {
...
}
Uploaded by
N2T
'iOS > Swift' 카테고리의 다른 글
Understanding Swift Performance (2) | 2023.03.13 |
---|---|
Explore structured concurrency in Swift (0) | 2023.02.11 |
Use async/await with URLSession (0) | 2023.02.11 |
Meet async/await in Swift (0) | 2023.02.11 |
Opaque Type (0) | 2023.02.11 |
댓글