Last active
July 18, 2022 11:19
-
-
Save krzyzanowskim/c0567f830f18158ab88b9ad7f99c0bb0 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Usage | |
@MainActor | |
final class AppSettings: ObservableObject { | |
static let standard = AppSettings() | |
@Published(preferenceKey: AppSettingsKey.editorHighlightSelectedLine) | |
var editorHighlightSelectedLine: Bool = true | |
} | |
enum AppSettingsKey: String { | |
case editorHighlightSelectedLine = "editor.HighlightSelectedLine" | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Foundation | |
import Combine | |
private var cancellables: Set<AnyCancellable> = [] | |
extension Published { | |
init<Key>(wrappedValue defaultValue: Value, preferenceKey: Key, store: UserDefaults = .standard) where Key: RawRepresentable, Key.RawValue == String { | |
self.init(wrappedValue: defaultValue, preferenceKey: preferenceKey.rawValue, store: store) | |
} | |
init(wrappedValue defaultValue: Value, preferenceKey: String, store: UserDefaults = .standard) { | |
let initialValue = store.value(forKey: preferenceKey) as? Value ?? defaultValue | |
self.init(initialValue: initialValue) | |
projectedValue.sink { value in | |
if let value = value as? AnyOptional, !value.isNil { | |
store.setValue(value, forKey: preferenceKey) | |
} else if let value = value as? AnyOptional, value.isNil { | |
store.removeObject(forKey: preferenceKey) | |
} else { | |
store.setValue(value, forKey: preferenceKey) | |
} | |
} | |
.store(in: &cancellables) | |
} | |
} | |
// Since our property wrapper's Value type isn't optional, but | |
// can still contain nil values, we'll have to introduce this | |
// protocol to enable us to cast any assigned value into a type | |
// that we can compare against nil: | |
private protocol AnyOptional { | |
var isNil: Bool { get } | |
} | |
extension Optional: AnyOptional { | |
var isNil: Bool { self == nil } | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment