// // Model.swift // Meta // // Created by david-swift on 19.07.2024. // import Foundation /// A model is a special type of state which can be updated from within itself. /// This is useful for complex asynchronous operations such as networking. /// /// Use the model protocol in the following way: /// ```swift /// struct TestView: View { /// /// @State private var test = TestModel() /// /// var view: Body { /// Button(test.test) { /// test.updateAsync() /// // You can also update via /// // test.test = "hello" /// // as with any state values /// } /// } /// /// } /// /// struct TestModel: Model { /// /// var test = "Label" /// /// var model: ModelData? // Use exactly this line in every model /// /// func updateAsync() { /// Task { /// // Do something asynchronously /// // Remember to execute the following line in the correct context, depending on the backend /// // As an example, you might have to run it on the main thread in some cases /// setModel { $0.test = "\(Int.random(in: 1...10))" } /// } /// } /// /// } /// /// ``` public protocol Model { /// Data about the model's state value. var model: ModelData? { get set } } /// Data about a model's state value. public struct ModelData { /// The state value's identifier. var id: UUID /// Whether to force update the views when this value changes. var force: Bool } extension Model { /// Update the model. /// - Parameter setModel: Update the model in this closure. public func setModel(_ setModel: (inout Self) -> Void) { guard let data = model else { return } var model = self setModel(&model) StateManager.setState(id: data.id, value: model) StateManager.updateState(id: data.id) StateManager.updateViews(force: data.force) } }