Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
import Foundation
@propertyWrapper struct Notifier<Value> {
private let identifier: String
var wrappedValue: Value? {
didSet {
NotificationCenter.default.post(name: Notification.Name(identifier), object: wrappedValue)
}
}
init(identifier: String) {
self.identifier = identifier
}
}
@propertyWrapper class Notified<Value> {
private let identifier: String
var wrappedValue: Value?
init(identifier: String) {
self.identifier = identifier
NotificationCenter.default.addObserver(forName: Notification.Name(identifier), object: nil, queue: nil, using: {[weak self] notification in
self?.wrappedValue = notification.object as? Value
})
}
}
struct Person {
@Notifier(identifier: "person.name.changed")
var name: String?
}
class Observer {
@Notified(identifier: "person.name.changed")
var name: String?
}
var person = Person()
var observer = Observer()
observer.name /// nil
person.name = "Hello world"
observer.name /// "Hello world"
@renaudjenny

This comment has been minimized.

Copy link

@renaudjenny renaudjenny commented May 8, 2020

This is really nice and a very good idea.

I would just add a restrictive enum to all of this for identifier key instead of IMO too permissive String:

enum NotificationCenterKey: String {
    case name = "person.name.changed"
}

@propertyWrapper struct Notifier<Value> {
    private let identifier: NotificationCenterKey

    var wrappedValue: Value? {
        didSet {
            NotificationCenter.default.post(name: Notification.Name(identifier.rawValue), object: wrappedValue)
        }
    }
    
    init(identifier: NotificationCenterKey) {
        self.identifier = identifier
    }
}

@propertyWrapper class Notified<Value> {
    private let identifier: NotificationCenterKey

    init(identifier: NotificationCenterKey) {
        self.identifier = identifier

        NotificationCenter.default.addObserver(forName: Notification.Name(identifier.rawValue), object: nil, queue: nil, using: {[weak self] notification in
              self?.wrappedValue = notification.object as? Value
        })
    }
}

struct Person {
  @Notifier(identifier: .name)
  var name: String?

}

class Observer {
  @Notified(identifier: .name)
  var name: String?
}

var person = Person()
var observer = Observer()

observer.name /// nil
person.name = "Hello world"
observer.name /// "Hello world"
@RuiAAPeres

This comment has been minimized.

Copy link
Owner Author

@RuiAAPeres RuiAAPeres commented May 8, 2020

Thank you renaudjenny!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment