This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| actor Foo { | |
| private var firstTask: Task<Void, Error>? | |
| func performFirstTask() async throws { | |
| // create unstructured concurrency | |
| let task = Task { | |
| try await … // the work associated with first task | |
| } | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| private func stream() -> AsyncThrowingStream<SomeData, Error> { | |
| AsyncThrowingStream<SomeData, Error> { continuation in | |
| let streamTask = Task { | |
| do { | |
| while !Task.isCancelled { | |
| guard let message = try await self.task?.receive() else { | |
| throw APIError.genericError | |
| } | |
| Self.logger.trace("\(SocketStrings.streamMessageYielded())") |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| extension ImageDownloader { | |
| // if you don't care about the order | |
| func downloadInRandomOrder() async -> [Image] { | |
| await withTaskGroup(of: Image.self) { group in | |
| let items = await fetchList() | |
| for item in items { | |
| group.addTask { await self.fetch(imageName: item.imageName) } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| func foo() async { | |
| await first() | |
| if await second() { | |
| // there several ways to run 3 and 4 in parallel; `async let`, shown here, is good pattern for fixed number of tasks; `TaskGroup` is good for variable number of tasks; both patterns keep you within realm of structured concurrency | |
| async let thirdTask: () = third() | |
| async let fourthTask: () = fourth() | |
| await thirdTask | |
| await fourthTask | |
| } else { | |
| // if 5 & 6 must run sequentially, then await 5 and then await 6 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| extension Sequence where Element: Hashable & Sendable { | |
| func dictionary<T: Sendable>(block: @escaping @Sendable (Element) async -> T) async -> [Element: T] { | |
| await withTaskGroup(of: (Element, T).self) { group in | |
| for id in self { | |
| group.addTask { (id, await block(id)) } | |
| } | |
| return await group.reduce(into: [:]) { $0[$1.0] = $1.1 } | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import SwiftUI | |
| import AsyncAlgorithms | |
| import os.log | |
| private let poi = OSSignposter(subsystem: "MyApp", category: .pointsOfInterest) | |
| typealias AsyncClosure = () async -> Void | |
| struct ExperimentView: View { | |
| @StateObject var viewModel = ExperimentViewModel() |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| func addSublayers(to view: UIView) { | |
| let radius: CGFloat = 150 | |
| let borderWidth: CGFloat = 10 | |
| let circleCenterOffset: CGFloat = 120 | |
| let startCenter = CGPoint(x: 200, y: 200) | |
| for i in 0..<3 { | |
| let shapeLayer = createShapeLayer() | |
| shapeLayer.path = circleDifference( | |
| center: point(startCenter, xOffset: CGFloat(i) * circleCenterOffset), |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // | |
| // URLSession+AsyncAwaitCompatibility.swift | |
| // | |
| // Copyright © Robert M. Ryan. All Rights Reserved. | |
| import Foundation | |
| import os.log | |
| private let log = OSLog(category: "URLSession+AsyncAwaitCompatibility") |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| class ViewController: UIViewController { | |
| private var task: Task<Void, Never>? | |
| override func viewDidLoad() { | |
| super.viewDidLoad() | |
| let task = Task { | |
| do { | |
| try await self.test() | |
| } catch is CancellationError { // this is another way to check for `CancellationError` |