14

I'm using Xcode 8 beta 5 and I'm trying to setup an enum of notifications like this

enum Notes: String {
  case note1
  case note2
}

Then trying to use them as the notification names

NotificationCenter.default.post(name: Notes.note1.rawValue as NSNotification.Name,
                                object: nil, userInfo: userInfo)

But I'm getting an error.

Cannot convert value of type 'String' to specified type 'NSNotification.Name'

Is there a work around, or am I missing something? It works in Xcode 7.3.1

Any help would be appreciated.

D. Greg
  • 991
  • 1
  • 9
  • 21

4 Answers4

39

Here you go, Use Swift 3 & Xcode 8.0

enum Notes: String {

    case note1 = "note1"
    case note2 = "note2"

    var notification : Notification.Name  {
        return Notification.Name(rawValue: self.rawValue )
    }
}

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        NotificationCenter.default.post(name: Notes.note2.notification ,object: nil, userInfo: nil)
    }
}

Another way

import UIKit

extension Notification.Name
{
    enum MyNames
    {
        static let Hello = Notification.Name(rawValue: "HelloThere")
    }
}

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        NotificationCenter.default.post(name: Notification.Name.MyNames.Hello ,object: nil, userInfo: nil)
    }
}
  • 1
    I think there is no reason to put 'enum MyNames' inside 'extension Notification.Name'. It just makes no sense. – m8labs Aug 26 '17 at 11:10
24

I am doing this way, For me this is more simple way to manage Notification names.

Swift 3.0 and Xcode 8.0

Using extension of Notification.Name, we can define static names inside that as following.

extension Notification.Name {
    static let newPasscodeSet = Notification.Name("newPasscodeSet")
    static let userLoggedIn = Notification.Name("userLoggedIn")
    static let notification3 = Notification.Name("notification3")
}

We can use that names like this:

 override func viewDidLoad() {
      NotificationCenter.default.addObserver(self, selector: #selector(self.newPasscodeSetAction), name: .newPasscodeSet, object: nil)
 }

 func newPasscodeSetAction() {
     // Code Here.
 }

Hope this simple way helpful for you.

Gaurav Rami
  • 1,287
  • 14
  • 21
  • The advantage of enum is all the cases will have `Notification.Name` type by default. It means if you add `extension Notification.Name: ExpressibleByStringLiteral` then it simplifies code a lot – Gargo Mar 16 '23 at 06:38
9

As far as I know, there was no type NSNotification.Name in Swift 2.2.1/SDKs bundled in Xcode 7.3.1, so I'm curious how you have made it work.

Anyway you need to write something like this if you want to utilize your enum:

NotificationCenter.default.post(name: NSNotification.Name(Notes.note1.rawValue),
                                object: nil, userInfo: userInfo)

By the way, my best recommendation to define your own Notification.Name is using extension which defines static properties:

extension Notification.Name {
    static let note1 = NSNotification.Name("note1")
    static let note2 = NSNotification.Name("note2")
}

(It's a little bit longer than enum..., but) you can use it like this:

NotificationCenter.default.post(name: .note1,
                                object: nil, userInfo: userInfo)
OOPer
  • 47,149
  • 6
  • 107
  • 142
  • You're right. There isn't `NSNotification.Name` in Swift 2.2. I meant that I could just assign the notification name with the raw value. I should have been more clear. – D. Greg Aug 11 '16 at 12:18
  • 1
    @D.Greg, thanks for clarification. As you know Swift betas are so rapidly changing, I was afraid I might be missing something. – OOPer Aug 11 '16 at 12:21
1

Maybe another approach in swift 4.2

extension Notification.Name{
   struct RecordListNotification {
        static let recordListDidChange:Notification.Name = Notification.Name("recordListDidChange")
        static let recordListTimeDidChange = Notification.Name("recordListTimeDidChange")
    }
}

and then

NotificationCenter.default.post(name: Notification.Name.RecordListNotification.recordListTimeDidChange, object: nil)

also to avoid verbose:

typealias RecordListNotification = Notification.Name.RecordListNotification

And it can be used:

NotificationCenter.default.post(name: RecordListNotification.recordListTimeDidChange, object: nil)
Reimond Hill
  • 4,278
  • 40
  • 52