Maybe you need to rethink your architecture?
This! Yes, whenever I find myself fighting the language, I suspect that I have a design issue. But you've illuminated a number of different things that I'd love to get your advice about, while my main original question was just using this as an example of something I run into all the time: having to use var foo: FooModel?
rather than let foo: FooModel
because of a reference to self
in the initializer.
But since you asked about the other, I'll pester you for advice! I'm trying to figure out how to bridge between SwiftUI
and SpriteKit
. My best guess so far looks like this. I know nothing, I'm all ears.
(Some of the names below aren't right, I'm pasting this stuff from versions from earlier this morning, but the code I'm working on does run, so if it matters I can fix it and show you a running thing.)
// This is the "real" model, the source of truth
class TumblerModel: ObservableObject {
var radius = TumblerRadius(0.5)
}
// This is the thing that controls the sprite, which is
// kind of a view of the TumblerModel, but also kind of a model
// itself? I'm still not super-strong with the whole view/model thing
class PixieModel: ObservableObject {
var radiusObserver: AnyCancellable!
let sprite: SKSpriteNode
init(radius: TumblerRadius) {
//...
radiusObserver = radius.publisher.sink(receiveValue: setRadius)
}
func setRadius(_ newRadius: Double) {
sprite.size = CGSize(width: newRadius * 2, height: newRadius * 2)
}
}
// This is my best guess about how to get the truth out to the sprites. I can
// use the "dollar" to connect it to a slider, for testing
// 🙏 https://www.swiftbysundell.com/basics/combine/
class TumblerRadius: ObservableObject {
var publisher: AnyPublisher<Double, Never> {
subject.eraseToAnyPublisher()
}
var dollar: Binding<Double> {
Binding(
get: { self.radius }, set: { self.radius = $0 }
)
}
var radius: Double {
didSet { subject.send(radius) }
}
init(_ radius: Double) { self.radius = radius }
private let subject = PassthroughSubject<Double, Never>()
}