How do you create custom notifications in Swift 3?
There is a cleaner (I think) way to achieve it
extension Notification.Name { static let onSelectedSkin = Notification.Name("on-selected-skin")}
And then you can use it like this
NotificationCenter.default.post(name: .onSelectedSkin, object: selectedSkin)
Notification.post is defined as:
public func post(name aName: NSNotification.Name, object anObject: AnyObject?)
In Objective-C, the notification name is a plain NSString. In Swift, it's defined as NSNotification.Name.
NSNotification.Name is defined as:
public struct Name : RawRepresentable, Equatable, Hashable, Comparable { public init(_ rawValue: String) public init(rawValue: String)}
This is kind of weird, since I would expect it to be an Enum, and not some custom struct with seemingly no more benefit.
There is a typealias in Notification for NSNotification.Name:
public typealias Name = NSNotification.Name
The confusing part is that both Notification and NSNotification exist in Swift
So in order to define your own custom notification, do somethine like:
public class MyClass { static let myNotification = Notification.Name("myNotification")}
Then to call it:
NotificationCenter.default().post(name: MyClass.myNotification, object: self)
You could also use a protocol for this
protocol NotificationName { var name: Notification.Name { get }}extension RawRepresentable where RawValue == String, Self: NotificationName { var name: Notification.Name { get { return Notification.Name(self.rawValue) } }}
And then define your notification names as an enum
anywhere you want. For example:
class MyClass { enum Notifications: String, NotificationName { case myNotification }}
And use it like
NotificationCenter.default.post(name: Notifications.myNotification.name, object: nil)
This way the notification names will be decoupled from the Foundation Notification.Name
. And you will only have to modify your protocol in case the implementation for Notification.Name
changes.