diff --git a/Sources/AppState/Application/Application+public.swift b/Sources/AppState/Application/Application+public.swift index e519d58..67695df 100644 --- a/Sources/AppState/Application/Application+public.swift +++ b/Sources/AppState/Application/Application+public.swift @@ -302,22 +302,17 @@ public extension Application { - Parameter keyPath: KeyPath of the state value to be fetched - Returns: The requested state of type `Value`. */ - static func state( - _ keyPath: KeyPath>, + static func state( + _ keyPath: KeyPath, _ fileID: StaticString = #fileID, _ function: StaticString = #function, _ line: Int = #line, _ column: Int = #column - ) -> State { + ) -> ApplicationState where ApplicationState.Value == Value { let appState = shared.value(keyPath: keyPath) - #if !os(Linux) && !os(Windows) - let debugEmoji = "🔄" - #else - let debugEmoji = "📦" - #endif log( - debug: "\(debugEmoji) Getting State \(String(describing: keyPath)) -> \(appState.value)", + debug: "\(ApplicationState.emoji) Getting State \(String(describing: keyPath)) -> \(appState.value)", fileID: fileID, function: function, line: line, diff --git a/Sources/AppState/Application/Types/Helper/MutableApplicationState.swift b/Sources/AppState/Application/Types/Helper/MutableApplicationState.swift index 09dc598..c6c827e 100644 --- a/Sources/AppState/Application/Types/Helper/MutableApplicationState.swift +++ b/Sources/AppState/Application/Types/Helper/MutableApplicationState.swift @@ -6,6 +6,13 @@ This protocol defines a type, `Value`, and a mutable property, `value`, of that public protocol MutableApplicationState { associatedtype Value + /// An emoji to use when logging about this state. + static var emoji: Character { get } + /// The actual value that this state holds. It can be both retrieved and modified. var value: Value { get set } } + +extension MutableApplicationState { + static var emoji: Character { "❓" } +} diff --git a/Sources/AppState/Application/Types/State/Application+FileState.swift b/Sources/AppState/Application/Types/State/Application+FileState.swift index 19768a9..c6526a5 100644 --- a/Sources/AppState/Application/Types/State/Application+FileState.swift +++ b/Sources/AppState/Application/Types/State/Application+FileState.swift @@ -8,6 +8,8 @@ extension Application { /// `FileState` encapsulates the value within the application's scope and allows any changes to be propagated throughout the scoped area. State is stored using `FileManager`. public struct FileState: MutableApplicationState { + public static var emoji: Character { "🗄️" } + @AppDependency(\.fileManager) private var fileManager: FileManager /// The initial value of the state. @@ -30,7 +32,7 @@ extension Application { } catch { log( error: error, - message: "🗄️ FileState Fetching", + message: "\(FileState.emoji) FileState Fetching", fileID: #fileID, function: #function, line: #line, @@ -51,7 +53,7 @@ extension Application { } catch { log( error: error, - message: "🗄️ FileState Deleting", + message: "\(FileState.emoji) FileState Deleting", fileID: #fileID, function: #function, line: #line, @@ -78,7 +80,7 @@ extension Application { } catch { log( error: error, - message: "🗄️ FileState Saving", + message: "\(FileState.emoji) FileState Saving", fileID: #fileID, function: #function, line: #line, diff --git a/Sources/AppState/Application/Types/State/Application+SecureState.swift b/Sources/AppState/Application/Types/State/Application+SecureState.swift index 53cab77..e77da2b 100644 --- a/Sources/AppState/Application/Types/State/Application+SecureState.swift +++ b/Sources/AppState/Application/Types/State/Application+SecureState.swift @@ -9,7 +9,9 @@ extension Application { } /// The SecureState structure provides secure and persistent key-value string storage backed by the Keychain that can be used across the application. - public struct SecureState { + public struct SecureState: MutableApplicationState { + public static var emoji: Character { "🔑" } + @AppDependency(\.keychain) private var keychain: Keychain /// The initial value of the state. diff --git a/Sources/AppState/Application/Types/State/Application+State.swift b/Sources/AppState/Application/Types/State/Application+State.swift index fcf525c..6527ef3 100644 --- a/Sources/AppState/Application/Types/State/Application+State.swift +++ b/Sources/AppState/Application/Types/State/Application+State.swift @@ -3,6 +3,7 @@ import Foundation extension Application { /// `State` encapsulates the value within the application's scope and allows any changes to be propagated throughout the scoped area. public struct State: MutableApplicationState, CustomStringConvertible { + /// Values that are available in the cache. enum StateType { case state case stored @@ -10,6 +11,14 @@ extension Application { case file } + public static var emoji: Character { + #if !os(Linux) && !os(Windows) + return "🔄" + #else + return "📦" + #endif + } + private let type: StateType /// A private backing storage for the value. diff --git a/Sources/AppState/Application/Types/State/Application+StoredState.swift b/Sources/AppState/Application/Types/State/Application+StoredState.swift index 988f21f..c3aef5a 100644 --- a/Sources/AppState/Application/Types/State/Application+StoredState.swift +++ b/Sources/AppState/Application/Types/State/Application+StoredState.swift @@ -8,6 +8,8 @@ extension Application { /// `StoredState` encapsulates the value within the application's scope and allows any changes to be propagated throughout the scoped area. State is stored using `UserDefaults`. public struct StoredState: MutableApplicationState { + public static var emoji: Character { "💾" } + @AppDependency(\.userDefaults) private var userDefaults: UserDefaults /// The initial value of the state. diff --git a/Sources/AppState/Application/Types/State/Application+SyncState.swift b/Sources/AppState/Application/Types/State/Application+SyncState.swift index 895afc1..37813b2 100644 --- a/Sources/AppState/Application/Types/State/Application+SyncState.swift +++ b/Sources/AppState/Application/Types/State/Application+SyncState.swift @@ -34,6 +34,8 @@ extension Application { - Warning: Avoid using this class for data that is essential to your app’s behavior when offline; instead, store such data directly into the local user defaults database. */ public struct SyncState: MutableApplicationState { + public static var emoji: Character { "☁️" } + @AppDependency(\.icloudStore) private var icloudStore: NSUbiquitousKeyValueStore /// The initial value of the state. @@ -76,7 +78,7 @@ extension Application { } catch { Application.log( error: error, - message: "☁️ SyncState failed to encode: \(newValue)", + message: "\(SyncState.emoji) SyncState failed to encode: \(newValue)", fileID: #fileID, function: #function, line: #line, diff --git a/Sources/AppState/PropertyWrappers/State/AppState.swift b/Sources/AppState/PropertyWrappers/State/AppState.swift index c59ef2b..48bdf1a 100644 --- a/Sources/AppState/PropertyWrappers/State/AppState.swift +++ b/Sources/AppState/PropertyWrappers/State/AppState.swift @@ -4,7 +4,7 @@ import SwiftUI #endif /// `AppState` is a property wrapper allowing SwiftUI views to subscribe to Application's state changes in a reactive way. Works similar to `State` and `Published`. -@propertyWrapper public struct AppState { +@propertyWrapper public struct AppState where ApplicationState.Value == Value { #if !os(Linux) && !os(Windows) /// Holds the singleton instance of `Application`. @ObservedObject private var app: Application = Application.shared @@ -14,7 +14,7 @@ import SwiftUI #endif /// Path for accessing `State` from Application. - private let keyPath: KeyPath> + private let keyPath: KeyPath private let fileID: StaticString private let function: StaticString @@ -33,14 +33,8 @@ import SwiftUI ).value } nonmutating set { - #if !os(Linux) && !os(Windows) - let debugEmoji = "🔄" - #else - let debugEmoji = "📦" - #endif - Application.log( - debug: "\(debugEmoji) Setting State \(String(describing: keyPath)) = \(newValue)", + debug: "\(ApplicationState.emoji) Setting State \(String(describing: keyPath)) = \(newValue)", fileID: fileID, function: function, line: line, @@ -68,7 +62,7 @@ import SwiftUI - Parameter keyPath: The `KeyPath` for accessing `State` in Application. */ public init( - _ keyPath: KeyPath>, + _ keyPath: KeyPath, _ fileID: StaticString = #fileID, _ function: StaticString = #function, _ line: Int = #line,