Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 8 additions & 5 deletions Sources/SwiftCrossUI/State/State.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import Foundation
// - It supports ObservableObject
// - It supports Optional<ObservableObject>
@propertyWrapper
public struct State<Value>: DynamicProperty, StateProperty {
public struct State<Value>: DynamicProperty, ObservableProperty {
class Storage {
// This inner box is what stays constant between view updates. The
// outer box (Storage) is used so that we can assign this box to
Expand Down Expand Up @@ -55,7 +55,7 @@ public struct State<Value>: DynamicProperty, StateProperty {

var storage: Storage

var didChange: Publisher {
public var didChange: Publisher {
storage.box.didChange
}

Expand Down Expand Up @@ -109,7 +109,7 @@ public struct State<Value>: DynamicProperty, StateProperty {
}
}

func tryRestoreFromSnapshot(_ snapshot: Data) {
public func tryRestoreFromSnapshot(_ snapshot: Data) {
guard
let decodable = Value.self as? Codable.Type,
let state = try? JSONDecoder().decode(decodable, from: snapshot)
Expand All @@ -120,7 +120,7 @@ public struct State<Value>: DynamicProperty, StateProperty {
storage.box.value = state as! Value
}

func snapshot() throws -> Data? {
public func snapshot() throws -> Data? {
if let value = storage.box as? Codable {
return try JSONEncoder().encode(value)
} else {
Expand All @@ -129,7 +129,10 @@ public struct State<Value>: DynamicProperty, StateProperty {
}
}

protocol StateProperty {
/// Declaring conformance to ObservableProperty is required for
/// SwiftCrossUI to automatically register an observer on the
/// conforming object's Publisher.
Comment on lines +132 to +134
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Update to;

/// View properties that conform to ObservableProperty are automatically observed by SwiftCrossUI.
///
/// This protocol is intended to be implemented by property wrappers. You shouldn't
/// have to implement it for your own model types.

public protocol ObservableProperty {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Move this protocol its own file now that it's part of the public API.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that ObservableProperty should inherit from DynamicProperty, because it doesn't make sense to implement an ObservableProperty whose state doesn't persist across view recalculations.

var didChange: Publisher { get }
func tryRestoreFromSnapshot(_ snapshot: Data)
func snapshot() throws -> Data?
Expand Down
2 changes: 1 addition & 1 deletion Sources/SwiftCrossUI/ViewGraph/ViewGraphNode.swift
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ public class ViewGraphNode<NodeView: View, Backend: AppBackend>: Sendable {
)
}

guard let value = property.value as? StateProperty else {
guard let value = property.value as? ObservableProperty else {
continue
}

Expand Down
4 changes: 2 additions & 2 deletions Sources/SwiftCrossUI/ViewGraph/ViewGraphSnapshotter.swift
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ public struct ViewGraphSnapshotter: ErasedViewGraphNodeTransformer {
let mirror = Mirror(reflecting: view)
for property in mirror.children {
guard
let stateProperty = property as? StateProperty,
let stateProperty = property as? ObservableProperty,
let propertyName = property.label,
let encodedState = state[propertyName]
else {
Expand All @@ -80,7 +80,7 @@ public struct ViewGraphSnapshotter: ErasedViewGraphNodeTransformer {
for property in mirror.children {
guard
let propertyName = property.label,
let property = property as? StateProperty,
let property = property as? ObservableProperty,
let encodedState = try? property.snapshot()
else {
continue
Expand Down
2 changes: 1 addition & 1 deletion Sources/SwiftCrossUI/_App.swift
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ class _App<AppRoot: App> {
)
}

guard let value = property.value as? StateProperty else {
guard let value = property.value as? ObservableProperty else {
continue
}

Expand Down
Loading