Created
October 31, 2024 06:59
-
-
Save Joannis/c237f8516a854cfd4acd5e7e36db9b0c 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 | |
| @MainActor class ViewModel: ObservableObject { | |
| private let events = AsyncStream<AwaitableEvent>.makeStream() | |
| struct AwaitableEvent { | |
| let event: Event | |
| let continuation: CheckedContinuation<Void, Never> | |
| } | |
| enum Event { | |
| case loadSomeData | |
| case exit | |
| } | |
| struct Post: Identifiable, Decodable { | |
| let id: Int | |
| let userId: Int | |
| let title: String | |
| let body: String | |
| } | |
| init() { | |
| bind() | |
| } | |
| @Published var posts: [Post] = [] | |
| func send(_ event: Event) async { | |
| return await withCheckedContinuation { continuation in | |
| let awaitable = AwaitableEvent( | |
| event: event, | |
| continuation: continuation | |
| ) | |
| events.continuation.yield(awaitable) | |
| } | |
| } | |
| func bind() { | |
| Task { | |
| for await awaitable in self.events.stream { | |
| switch awaitable.event { | |
| case .loadSomeData: | |
| try? await self.loadDataMainActor() | |
| case .exit: | |
| exit(0) // hoorayy! | |
| } | |
| awaitable.continuation.resume() | |
| } | |
| } | |
| } | |
| func loadDataMainActor() async throws{ | |
| posts = [] | |
| let url = URL(string: "https://jsonplaceholder.typicode.com/posts")! | |
| let (data, _) = try await URLSession.shared.data(from: url) | |
| do { | |
| posts = try JSONDecoder().decode([Post].self, from: data) | |
| } catch { | |
| print("error=\(error)") | |
| } | |
| print("posts.count=\(posts.count)") | |
| } | |
| } | |
| struct ContentView: View { | |
| @StateObject var viewModel: ViewModel | |
| var body: some View { | |
| List(viewModel.posts) { row in | |
| Text("Row \(row)") | |
| } | |
| .refreshable { | |
| print("[aaa] Refreshable.start") | |
| await viewModel.send(.loadSomeData) | |
| print("[aaa] Refreshable.end") | |
| } | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment