この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
Swift で NSNotification の userInfo を扱う
個人的にハマったので情報共有。
Swift で NSNotification の userInfo を使おうと思った場合、Objective-C ほど簡単には扱えません。
userInfo の型は次のようになっているので、Optional Value やら AnyObject やらで、アンラップしたりキャストしたりする必要があります。
class NSNotification : NSObject, NSCopying, NSCoding {
// ...
var userInfo: [NSObject : AnyObject]? { get }
// ...
}
色々調べて試した結果、次の2通りのパターンのどちらかを使うのがいいのではないかと思いました。
- 変数宣言時にアンラップ & キャストする
- Value-Binding 時にアンラップ & キャストする
サンプルコード
1. 変数宣言時にアンラップ & キャストする
if let userInfo = notification.userInfo {
let value = userInfo["number"]! as Int
let plus10 = value + 10
println(plus10)
}
2. Value-Binding 時にアンラップ & キャストする
if let userInfo = notification.userInfo as [String: Int]! {
let value = userInfo["number"]!
let plus10 = value + 10
println(plus10)
}
私はアンラップが1回で済むので、前者のほうが好きです。
また、次のように短く書くこともできますが、userInfo が nil の場合にランタイムエラーとなるので、あまりオススメはしません。
let value = notification.userInfo!["number"]! as Int
let plus10 = value + 10
println(plus10)
フルサンプルコード
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let nc = NSNotificationCenter.defaultCenter()
// 登録
nc.addObserver(self, selector: "handleTestNotification:", name: "testNotification", object: nil)
// 通知
nc.postNotificationName("testNotification", object: nil, userInfo: ["number": 100])
}
func handleTestNotification(notification: NSNotification) {
// 変数宣言時にアンラップ & キャストする方法
if let userInfo = notification.userInfo {
let value = userInfo["number"]! as Int
let plus10 = value + 10
println(plus10)
}
// Value-Binding 時にアンラップ & キャストする方法
if let userInfo = notification.userInfo as [String: Int]! {
let value = userInfo["number"]!
let plus10 = value + 10
println(plus10)
}
// 1行で書く方法。ただしuserInfoがnilの場合はランタイムエラー
let value = notification.userInfo!["number"]! as Int
let plus10 = value + 10
println(plus10)
}
}
まとめ
Swift は type safe な言語になっているため、Objective-C よりも細かく型を意識しなければなりません。
はじめは少し難しいですが、一つ一つ身につけていきましょう。