Last active
June 5, 2024 15:45
-
-
Save robertmryan/c1911e7ddfece63edae85c46be1c76c5 to your computer and use it in GitHub Desktop.
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() | |
| var body: some View { | |
| VStack { | |
| Button("Red") { Task { await viewModel.addRed() } } | |
| Button("Green") { Task { await viewModel.addGreen() } } | |
| Button("Blue") { Task { await viewModel.addBlue() } } | |
| } | |
| .task { | |
| await viewModel.monitorChannel() | |
| } | |
| } | |
| } | |
| @MainActor | |
| class ExperimentViewModel: ObservableObject { | |
| let channel = AsyncChannel<AsyncClosure>() | |
| func monitorChannel() async { | |
| for await block in channel { | |
| await block() | |
| } | |
| } | |
| func addRed() async { | |
| poi.emitEvent(#function) | |
| await channel.send { await self.red() } | |
| } | |
| func addGreen() async { | |
| poi.emitEvent(#function) | |
| await channel.send { await self.green() } | |
| } | |
| func addBlue() async { | |
| poi.emitEvent(#function) | |
| await channel.send { await self.blue() } | |
| } | |
| func red() async { | |
| let state = poi.beginInterval(#function) | |
| defer { poi.endInterval(#function, state) } | |
| try? await Task.sleep(for: .seconds(3)) | |
| } | |
| func green() async { | |
| let state = poi.beginInterval(#function) | |
| defer { poi.endInterval(#function, state) } | |
| try? await Task.sleep(for: .seconds(3)) | |
| } | |
| func blue() async { | |
| let state = poi.beginInterval(#function) | |
| defer { poi.endInterval(#function, state) } | |
| try? await Task.sleep(for: .seconds(3)) | |
| } | |
| } |
Author
Author
FWIW, in case anyone is interested in how I generated the multicolored intervals in my original answer, see CustomPointsOfInterest. But it is not immediately relevant to the question at hand, but was merely a nice visual way of associating the red, green, and blue intervals with the associated functions in my original answer. But I have excised it from my MRE above (and the associated repo) for the sake of simplicity.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Unlike my original answer, this is using standard “Points of Interest” tool, so the graph looks less colorful, but doesn’t require you to install my custom point of interest tool:
But the idea is the same. I rapidly tapped “red”, “green”, and “blue” buttons in succession, repeating the process three times. I then repeated the exercise, but this second time, I dismissed the view in question before it was completed, thereby canceling the channel (and its associated tasks).