Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
[danielbernal.co] Protocols and Combine: Using @published in your Protocol declaration - https://danielbernal.co/combine-and-protocols-in-swift/
class AnimalGenerator: Generator, ObservableObject {
@Published private(set) var name: String = ""
var namePublished: Published<String> { _name }
var namePublisher: Published<String>.Publisher { $name }
let animals = ["Cat", "Dog", "Crow", "Horse", "Iguana", "Cow", "Racoon"]
init() {
generate()
}
func generate() {
self.name = animals.randomElement() ?? ""
}
}
class AnimalGenerator: Generator, ObservableObject {
@Published private(set) var name: String = ""
let animals = ["Cat", "Dog", "Crow", "Horse", "Iguana", "Cow", "Racoon"]
init() {
generate()
}
func generate() {
self.name = animals.randomElement() ?? ""
}
}
protocol Generator {
// Wrapped value
var name: String { get }
// (Published property wrapper)
var namePublished: Published<String> { get }
// Publisher
var namePublisher: Published<String>.Publisher { get }
func generate()
}
protocol Generator {
@Published var name: String { get }
func generate()
}
import PlaygroundSupport
import SwiftUI
import Combine
class AnimalGenerator: ObservableObject {
@Published private(set) var name: String = ""
let animals = ["Cat", "Dog", "Crow", "Horse", "Iguana", "Cow", "Racoon"]
init() {
generate()
}
func generate() {
self.name = animals.randomElement() ?? ""
}
}
class TheViewModel: ObservableObject {
@Published var displayData: String = "No data"
var generator: AnimalGenerator = AnimalGenerator()
var cancellable: AnyCancellable?
init() {
cancellable =
generator
.$name
.receive(on: RunLoop.main)
.sink { [weak self] data in
self?.displayData = data
}
}
func generate() {
generator.generate()
}
}
struct TheView: View {
@ObservedObject var viewModel: TheViewModel = TheViewModel()
var body: some View {
VStack {
Text(viewModel.displayData).font(.system(.largeTitle)).padding()
Button("Tap me", action: { self.viewModel.generate() })
}
}
}
PlaygroundPage.current.setLiveView(TheView())
class PersonGenerator: Generator, ObservableObject {
var namePublished: Published<String> { _name }
var namePublisher: Published<String>.Publisher { $name }
@Published private(set) var name: String = ""
let persons = ["John", "Jane", "Carlos", "Daniel", "Helen", "David", "Bill"]
init() {
generate()
}
func generate() {
self.name = persons.randomElement() ?? ""
}
}
let viewModel = TheViewModel(generator: PersonGenerator())
PlaygroundPage.current.setLiveView(
TheView(viewModel: viewModel)
)
struct TheView: View {
@ObservedObject var viewModel: TheViewModel
var body: some View {
VStack {
Text(viewModel.textToShow).font(.system(.largeTitle)).padding()
Button("Tap me", action: { self.viewModel.generate() })
}
}
}
struct TheView: View {
@ObservedObject var viewModel: TheViewModel = TheViewModel(generator: AnimalGenerator())
var body: some View {
VStack {
Text(viewModel.textToShow).font(.system(.largeTitle)).padding()
Button("Tap me", action: { self.viewModel.generate() })
}
}
}
class TheViewModel: ObservableObject {
@Published var textToShow: String = "No data"
var generator: Generator
var cancellable: AnyCancellable?
init(generator: Generator) {
self.generator = generator
cancellable =
generator
.namePublisher
.receive(on: RunLoop.main)
.sink { [weak self] data in
self?.textToShow = data
}
}
func generate() {
generator.generate()
}
}
let viewModel: TheViewModel = TheViewModel(generator: AnimalGenerator())
PlaygroundPage.current.setLiveView(
TheView(viewModel: viewModel)
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment