Created
December 15, 2021 05:14
-
-
Save garsdle/ad2562e398d84070d2c8f729fa19588a 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 Combine | |
@propertyWrapper | |
struct Streamed<Value: Sendable> { | |
var wrappedValue: Value { | |
didSet { | |
onCountUpdate(wrappedValue) | |
} | |
} | |
var projectedValue = AsyncStream<Value> { _ in } | |
private var onCountUpdate: ((Value) -> Void) = { _ in } | |
init(wrappedValue: Value) { | |
self.wrappedValue = wrappedValue | |
self.projectedValue = AsyncStream<Value> { continuation in | |
self.onCountUpdate = { newValue in | |
continuation.yield(newValue) | |
} | |
} | |
onCountUpdate(wrappedValue) | |
} | |
} | |
actor Store { | |
static var shared = Store() | |
@Streamed | |
var count = 1 | |
func incrementCount() async { | |
count += 1 | |
} | |
} | |
@MainActor | |
class ViewModel: ObservableObject { | |
@Published var count = 0 | |
init() { | |
Task { [unowned self] in | |
for await count in await Store.shared.$count { | |
self.count = count | |
} | |
} | |
} | |
} | |
struct ContentView: View { | |
@StateObject var viewModel = ViewModel() | |
var body: some View { | |
VStack { | |
Text("\(viewModel.count)") | |
Button("Increment", action: incrementCount) | |
} | |
} | |
func incrementCount() { | |
Task { | |
await Store.shared.incrementCount() | |
} | |
} | |
} | |
struct ContentView_Previews: PreviewProvider { | |
static var previews: some View { | |
ContentView() | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment