Qiitaで面白い記事を読みました。
Swiftでイベントをタイプセーフに送受信できるライブラリEventHubを書きました。 - Qiita
その影響で(?)、自分でも通知周りの処理を書いてみました。
動作を確認した環境
環境 | 情報 |
---|---|
Xcode | 7.3 (7D175) |
iOS | 9.3 |
Swift | 2.2 |
Date | 2016/3/25 |
使い方
・通知を区別するenumに、通知を実装したプロトコルを適用しておきます
enum PenTest: NotificationProtocol {
case White
case Gray
case Black
}
・Observerの登録
PenTest.White.addObserver(self) { [weak self] in
self?.stateLabel.text = "\(NSDate())"
}
・通知の送信
PenTest.White.postNotify()
自分で作ったenumがそのまま通知の識別子になって、そのまま送受信に使えるようになります。enumに適用する事を想定して作られていますが、何にでも使えるはずです。たぶん。
通知に関する処理はprotocol extension経由で実装されてるので、プロトコルの適用以外にする事はありません。
ソースコード
こんな感じです。
import Foundation
/// 通知関係のプロトコル
protocol NotificationProtocol {
func addObserver(observer: AnyObject, block: (()->Void))
func postNotify()
}
/// 通知関係の実装
extension NotificationProtocol where Self: Equatable {
func addObserver(observer: AnyObject, block: (()->Void)) {
let notify = NotificationCenter.Observer(key: self, observer: observer, block: block)
NotificationCenter.observerArray.append(notify)
}
func postNotify() {
NotificationCenter.flash()
for ob in NotificationCenter.observerArray {
if let key = ob.key as? Self where key == self {
if let block = ob.block as? (()->Void) {
block()
}
}
}
}
}
/// 通知の管理をするための下請け構造体
struct NotificationCenter {
struct Observer {
let key: NotificationProtocol
weak var observer: AnyObject?
let block: Any?
}
static var observerArray = [Observer]()
/// 不要になったObserverを排除
static func flash() {
observerArray = observerArray.filter() { ob in ob.observer != nil }
}
}
問題点
- 通知に付随する情報を送る事が出来ません
- スレッド関係の事を考慮していません
- 真面目にテストしてません
『protocol extensionでこんな事が出来るよ』ってサンプル程度に見て下さい。