Swift3의 NotificationCenter를 지금까지와 가까운 형태로 사용해보기
회전 오른쪽.
※이하의 내용은 일단 아카이브로서 남겨 둡니다만, 좋은 사용법이 아니기 때문에 양해 바랍니다.
Swift3.0에서 변경된 NSNotificationCenter
Swift2에서 Swift3으로 바뀌고, Foundation계에도 손이 가해져
NSNotificationCenter
주위에도 변경이 있었습니다.Swift2.2와 Swift3.0에서 addObserve하는 경우의 동일한 처리를 비교해 보겠습니다.
Swift2
class Hoge {
@objc func doSomething(notification: Notification) {
// ...
}
}
NSNotificationCenter.defaultCenter().addObserver(
self,
selector: #selector(hoge.doSomething(_:)),
name: "NotificationKey",
object: nil
)
Swift3
class Hoge {
@objc func doSomething(_ notification: Notification) {
// ...
}
}
let hoge = Hoge()
NotificationCenter.default.addObserver(
hoge,
selector: #selector(hoge.doSomething(_:)),
name: NSNotification.Name("NotificationKey"), //おや...?
object: nil
)
여기서 NSNotification.Name 라는 익숙하지 않은 것이 나왔습니다.
(덧붙여서 Notification.Name 의 것도 있어, 추적하면 NSNotification.Name 의 앨리어스(alias)가 되어 있으므로 거의 동의입니다. 어느쪽으로 써도 실수는 아닐 것.)
아무래도 Swift3 에서는 통지를 발행하기 위한
name
는 String
가 아니고 이 NSNotification.Name
를 사용할 수 있게 된 것 같습니다.그러나 이것마다
NSNotification.Name("SomeNotificationKey")
하는 것이 힘들지요.
그래서, 지금까지 그대로의 형태에 가까운 느낌으로 사용할 수 있도록 해 봅니다.
마법을 걸다
가능하면 지금까지와 같이
name: "NotificationKey"
라고 쓰고 싶으므로, NSNotification.Name 에 마법을 겁니다.여기서 ExpressibleByStringLiteral 이라는 프로토콜의 차례가 됩니다.
그건 그렇고,이 ExpressibleByStringLiteral은 Swift2에서 StringLiteralConvertible이라는 이름이었습니다.
ExpressibleByStringLiteral을 Notification.Name에 적용
extension NSNotification.Name: ExpressibleByStringLiteral {
public init(unicodeScalarLiteral value: String) {
self.init(rawValue: value)
}
public init(extendedGraphemeClusterLiteral value: String) {
self.init(rawValue: value)
}
public init(stringLiteral value: String) {
self.init(rawValue: value)
}
}
이렇게함으로써,
// good!
NotificationCenter.default.addObserver(
hoge,
selector: #selector(hoge.doSomething(_:)),
name: "NotificationKey",
object: nil
)
이와 같이, 문자 리터럴(
""
)를 사용해 지금까지 대로의 쓰는 방법을 할 수 있게 됩니다.... 네, 이것이 변수라면 어떻게합니까? 네요.
이 경우 변수를 정의하는 형식을 Notification.Name으로 지정합니다.
class Hoge {
// 左辺側で型を指定してあげることで、右辺はStringではなくて、Notification.Nameと推論される
static let NotificationKey: NSNotification.Name = "NotificationKey"
// NG : 今までどおりの宣言だと、Stringと推論される
// static let NotificationKey = "NotificationKey"
@objc func doSomething(_ notification: Notification) {
// ...
}
}
// good!
NotificationCenter.default.addObserver(
hoge,
selector: #selector(hoge.doSomething(_:)),
name: Hoge.NotificationKey, // 今までどおりいける!
object: nil
)
요약
Swift3가 되어 NSNotification.Name 라든지 나와서 조금 겁났습니다만, 조금 궁리해 주면 취급하기 쉬워질지도 모릅니다. ExpressibleByStringLiteral 감사합니다.
덤
거기 이용 빈도가 높은,
UIApplicationDidBecomeActiveNotification
와 같은 UIApplication 주위의 Notification의 key에 관해서는,// swift2まではこれ
UIApplicationDidBecomeActiveNotification
// swift3からはこれ
NSNotification.Name.UIApplicationDidBecomeActive
같이 바뀌었기 때문에 조심합시다. 어쩌면 자동 마이그레이션되어 보완이 효과가 있을지도 모릅니다만. . .
(처음 어디로 갔는지 알아차리지 않았다...)
(※ 참고 Xcode8 beta6 시점의 Swift3.0을 기반으로 쓰고 있습니다.
Reference
이 문제에 관하여(Swift3의 NotificationCenter를 지금까지와 가까운 형태로 사용해보기), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/sgr-ksmt/items/55039bddb08cb8ebc90c텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)