Is this the right way to declare a notification name in Swift 3?

I noticed that the Swift 3 converter wrapped all of my NSNotification notification names in Notification.Name(rawValue: ) at the call sites, but I already declare my notification names, and so this conversion results in bulky call sites. I am wondering if there is a new best practice that I should be following instead that makes my notification names more consistent with system notifications, to keep my call sites clean.


For example, I have a notification name previously declared like this:


public let kContentAddedNotification = "contentAdded"


As of Swift 3, this causes the call site look like this:


        NotificationCenter.default().post(name: Notification.Name(rawValue: kContentAddedNotification), object: self)


Based on how the system notifications are being synthesized, it would appear that I should declare notification names more like this:


public extension Notification.Name {
    public static let contentAdded = Notification.Name("ContentAdded")
}


In the call site, it would appear like this:


        NotificationCenter.default().post(name: .contentAdded, object: self)


So, is this the right syntax for declaring a notification name in Swift 3?

Replies

See this article:

Migrating to Swift 3

Which contains descriptions about Notification.Name:

static let MyGreatNotification = Notification.Name("MyGreatNotification")
NotificationCenter.default().post(name: MyController.MyGreatNotification, object: self)


Your way of making type property looks smart, but it is not the "only" right way.


Notification.Name is a thin wrapper for NSString, which is internally used as notification names.

You just need to convert the value type to Notification.Name, other than that, do it in your own way.

Old thread, I know, but to me this is the easiest way to handle notifications:


extension Notification.Name {
    static let ParticipantJoined = Notification.Name("Participant Joined")
  
    func post(object: Any? = nil, userInfo: [AnyHashable : Any]? = nil) {
        NotificationCenter.default.post(name: self, object: object, userInfo: userInfo)
    }

    @discardableResult
    func onPost(object: Any? = nil, queue: OperationQueue? = nil, using: @escaping (Notification) -> Void) -> NSObjectProtocol {
        return NotificationCenter.default.addObserver(forName: self, object: object, queue: queue, using: using)
    }
}


Now when you want to post a norification with no details, which is the most common usage, you just do:

Notification.Name.ParticipantJoined.post()


And to "catch" it you just do:

Notification.Name.ParticipantJoined.onPost { [weak self] note in
   guard let `self` = self else { return }
    // Do your stuff here
}



Having to get the NotificationCenter involved in your code is just redundant and harder to read, IMHO. I'm working with a Notification, not a NotificationCenter, so why not hide it away? 🙂

Having to get the NotificationCenter involved in your code is just redundant and harder to read, IMHO.

Fair enough. You could extend this by having your methods take a

center
parameter that defaults to
NotificationCenter.default
. That was most folks could skip that parameter entirely, while folks with wacky requirements could pass in a specific center.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"