Swift 3 - Как использовать значение enum raw как NSNotification.Name?

Я использую Xcode 8 beta 5, и я пытаюсь настроить перечисление таких уведомлений

enum Notes: String {
  case note1
  case note2
}

Затем, пытаясь использовать их в качестве имен уведомлений

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

Но я получаю сообщение об ошибке.

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

Есть ли работа, или я чего-то не хватает? Он работает в Xcode 7.3.1

Любая помощь будет оценена.

Ответ 1

Здесь вы идете, используйте 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)
    }
}

Другой способ

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)
    }
}

Ответ 2

Я делаю так, для меня это более простой способ управлять именами уведомлений.

Swift 3.0 и Xcode 8.0

Используя расширение имени Notification.Name, мы можем определить статические имена внутри этого, как показано ниже.

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

Мы можем использовать эти имена следующим образом:

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

 func newPasscodeSetAction() {
     // Code Here.
 }

Надеюсь, что этот простой способ поможет вам.

Ответ 3

Насколько я знаю, в Swift 2.2.1/SDK в Xcode 7.3.1 не было типа NSNotification.Name, поэтому мне интересно, как вы его работали.

В любом случае вам нужно написать что-то вроде этого, если вы хотите использовать перечисление:

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

Кстати, моя лучшая рекомендация по определению вашего собственного Notification.Name заключается в использовании расширения, которое определяет статические свойства:

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

(Это немного длиннее, чем enum..., но) вы можете использовать его следующим образом:

NotificationCenter.default.post(name: .note1,
                                object: nil, userInfo: userInfo)