优化 Swift 中 Notification.Name 的使用方式

Swift 中使用通知,在写通知名称的时候,并不能像 Objective-C 那样简单方便,一个字符串搞定。刚开始使用 Swift 通知时,感觉各种不爽,需要这样写:

1
Notification.Name("myNotification")

光取个名字就需要这么长一串代码,真的有悖于 Swift 给我的那种简洁的印象。下面我们就来优化一下。

方法一:简单粗暴的 Notification.Name 扩展


最简单的方式就是对 Notification.Name 进行扩展,代码如下:

1
2
3
extension Notification.Name {
static let myNotification = Notification.Name("myNotification")
}

使用的时候就能用点进行调用了:

1
NotificationCenter.default.post(name: .myNotification, object: nil)

一瞬间简单了不少。不过还不够,我希望自定义的通知名称与系统的分开,并且如果一个编程不规范的人可能还会犯 namespace 错误。Swift中Notification.Name这么难用怎么办 这篇文章给了我灵感。

方法二:使用 Enum 定义自己的通知名称


首先我们要新建一个枚举类型 NotificationNames ,为了避免 namespace 的问题,声明一个计算属性,添加一个前缀,就好像以前 Objective-C 的前缀 NS 一样。

1
2
3
4
5
6
7
8
9
10
11
12
enum NotificationNames: String {

case myNotification

var nameValue: String {
return "NN" + rawValue
}

var notiName: Notification.Name {
return Notification.Name(nameValue)
}
}

再添加一个自定义的 post 函数,方便调用。

1
2
3
func post(_ name: NotificationNames, object myObject: AnyObject? = nil) {
NotificationCenter.default.post(name: name.notiName, object: myObject)
}

使用起来就简单了:

1
NotificationCenter.default.post(.myNotification, object: nil)

当在 NotificationNames 类型参数输入点的时候,就会很快的列出我们自定义的名称了。

类似的,RxSwift 版本的扩展如下:

1
2
3
4
5
6
extension Reactive where Base: NotificationCenter {

func notification(_ myName: NotificationNames, object: AnyObject? = nil) -> Observable<Notification> {
return notification(myName.notiName, object: object)
}
}

使用如下:

1
2
3
4
5
6
NotificationCenter.default
.rx.notification(.myNotification, object: nil)
.subscribe(onNext: { _ in
// code
})
.addDisposableTo(bag)

参考: Swift中Notification.Name这么难用怎么办