如何在Swift中通过通知发送枚举值?

6
我想在通知中以对象形式发送一个枚举类型:
enum RuleError:String {
    case Create, Update, Delete
}

class myClass {

   func foo() {
       NSNotificationCenter.defaultCenter().postNotificationName("RuleFailNotification", 
                                            object: RuleError.Create)
   }
}

很遗憾,这种方法行不通,因为枚举类型不能匹配AnyObject?

有什么办法可以解决这个问题吗?

4个回答

8
您正在使用的函数中的object参数是发送通知的对象,而不是参数。请查看此处的文档(链接)。 您应该将要发送的枚举值作为参数放入用户信息字典中,并使用以下方法:
func postNotificationName(_ aName: String,
                   object anObject: AnyObject?,
                 userInfo aUserInfo: [NSObject : AnyObject]?)

在你的情况下:
let userInfo = ["RuleError" : RuleError.Create.rawValue]

NSNotificationCenter.defaultCenter().postNotificationName("RuleFailNotification",
        object: self,
        userInfo:userInfo)

为了处理通知,首先需要注册它:

NSNotificationCenter.defaultCenter().addObserver(
        self,
        selector: "handleRuleFailNotification:",
        name: "RuleFailNotification",
        object: nil)

然后处理它:
func handleRuleFailNotification(notification: NSNotification) {

        let userInfo = notification.userInfo

        RuleError(rawValue: userInfo!["RuleError"] as! String)
    }

1
这是一种不幸的必要性。通知将枚举和结构体强制转换为二等公民。我认为这是 Swift 的一个主要缺点,因为枚举通常只是受限制的 Int 或 String,但这些作为值是可以接受的。 - BaseZen

2
最简单的解决方案是发送原始值。
RuleError.Create.rawValue

这可以稍后转换回枚举类型

RuleError(rawValue : "Create")

但是object参数不适合发送自定义数据。最好使用userInfo字典。


1

你可以使用boxing将像枚举这样的原生Swift类型通过NSNotification发送。

final class Box<T>: NSObject {
   let value: T
   init(_ value: T) {
      self.value = value
   }
}

发布通知:

要发布通知:

let userInfo = ["RuleError" : Box(RuleError.Create)]
NSNotificationCenter.defaultCenter().postNotificationName("RuleFailNotification",
    object: self,
    userInfo:userInfo)

在您的观察者中,该值可以被检索为:

if let box = notification.userInfo?["RuleFailNotification"] as? Box<RuleError> {
    let ruleError = box.value
}

你可以发送一个带有关联值的Swift枚举。

在最后的代码块中,应该是userInfo?["RuleError"]吧? - SKerkewitz

0

示例. Swift 3

1: 创建通知名称

extension NSNotification.Name {
   public static let NetworkReachabilityStatus: NSNotification.Name = 
   NSNotification.Name(rawValue: "NetworkReachabilityStatusChanged")
}

2:一些枚举

enum NetworkReachabilityStatus {
  case connected
  case notConnected
}

3:发布数据

NotificationCenter.default.post(name: Notification.Name.NetworkReachabilityStatus,
                  object:nil,
                  userInfo:[kNetworkRechabilityStatus: NetworkReachabilityStatus.notConnected])
  • kNetworkRechabilityStatus - 是字符串常量

4:观察

override func viewDidLoad() {
    super.viewDidLoad()
    NotificationCenter.default.addObserver(self, selector: #selector(networkStatusChanged(_:)), name: Notification.Name.NetworkReachabilityStatus, object: nil)
}

func networkStatusChanged(_ notification: Notification) {
    let status: NetworkReachabilityStatus = notification.userInfo?[kNetworkRechabilityStatus] as! NetworkReachabilityStatus
    switch status {
    case .connected:

        break
    case .notConnected:

        break
    }
}

别忘了取消订阅通知 :)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接