Created
June 27, 2020 20:24
-
-
Save IanKeen/d78e3a1a22e762f62b3eba9ad3bdcc28 to your computer and use it in GitHub Desktop.
PropertyWrapper: Delegate updates similar to SwiftUIs ObservableObject/Published combo
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
| public protocol DelegateProvider: AnyObject { | |
| static func notifyDelegate(_ instance: Self) | |
| } | |
| @propertyWrapper | |
| public struct Delegate<Value> { | |
| public var wrappedValue: Value | |
| public init(wrappedValue: Value) { | |
| self.wrappedValue = wrappedValue | |
| } | |
| public static subscript<Instance: DelegateProvider>( | |
| _enclosingInstance instance: Instance, | |
| wrapped wrappedKeyPath: ReferenceWritableKeyPath<Instance, Value>, | |
| storage storageKeyPath: ReferenceWritableKeyPath<Instance, Self> | |
| ) -> Value { | |
| get { | |
| return instance[keyPath: storageKeyPath].wrappedValue | |
| } | |
| set { | |
| instance[keyPath: storageKeyPath].wrappedValue = newValue | |
| Instance.notifyDelegate(instance) | |
| } | |
| } | |
| } |
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
| // Updating any of the properties marked `@Delegate` will notify the delegate | |
| protocol ViewModelDelegate: AnyObject { | |
| func viewModelUpdated(_ viewModel: ViewModel) | |
| } | |
| class ViewModel: DelegateProvider { | |
| static func notifyDelegate(_ instance: ViewModel) { | |
| instance.delegate?.viewModelUpdated(instance) | |
| } | |
| @Delegate private(set) var foo: Int = 0 | |
| @Delegate private(set) var bar: String = "" | |
| @Delegate private(set) var baz: [Bool] = [] | |
| weak var delegate: ViewModelDelegate? { // property wrappers dont work with `weak` :( | |
| didSet { Self.notifyDelegate(self) } | |
| } | |
| init() { } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment