Swiftのオブザーバをデフォルトの通知センターにどのように追加しますか?バッテリー残量が変化したときに通知を送信するこのコード行を移植しようとしています。
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(batteryLevelChanged:) name:UIDeviceBatteryLevelDidChangeNotification object:nil];
Objective-C APIと同じですが、Swiftの構文を使用します。
NSNotificationCenter.defaultCenter().addObserver(
self,
selector: #selector(batteryLevelChanged:),
name: UIDeviceBatteryLevelDidChangeNotification,
object: nil)
スイフト3:
NotificationCenter.default.addObserver(
self,
selector: #selector(self.batteryLevelChanged:),
name: .UIDeviceBatteryLevelDidChange,
object: nil)
Swift 4.2:
NotificationCenter.default.addObserver(
self,
selector: #selector(self.batteryLevelChanged),
name: UIDevice.batteryLevelDidChangeNotification,
object: nil)
オブザーバがObjective-Cオブジェクトから継承しない場合は、セレクタとして使用するために、メソッドの前に@objc
を付ける必要があります。
@objc private func batteryLevelChanged(notification: NSNotification){
//do stuff using the userInfo property of the notification object
}
通知の送信(ポスト):
NotificationCenter.default.post(name: Notification.Name("NotificationIdentifier"), object: nil)
_または_
NotificationCenter.default.post(name: Notification.Name("NotificationIdentifier"), object: nil, userInfo: ["Renish":"Dadhaniya"])
通知を受け取る(取得):
NotificationCenter.default.addObserver(self, selector: #selector(self.methodOfReceivedNotification(notification:)), name: Notification.Name("NotificationIdentifier"), object: nil)
受信した通知のFunction-Methodハンドラ:
@objc func methodOfReceivedNotification(notification: Notification) {}
通知の送信(ポスト):
NotificationCenter.default.post(name: Notification.Name("NotificationIdentifier"), object: nil)
通知を受け取る(取得):
NotificationCenter.default.addObserver(self, selector: #selector(YourClassName.methodOfReceivedNotification(notification:)), name: Notification.Name("NotificationIdentifier"), object: nil)
受信した通知のメソッドハンドラ:
func methodOfReceivedNotification(notification: Notification) {
// Take Action on Notification
}
通知を削除します。
deinit {
NotificationCenter.default.removeObserver(self, name: Notification.Name("NotificationIdentifier"), object: nil)
}
通知を送信(ポスト)
NSNotificationCenter.defaultCenter().postNotificationName("NotificationIdentifier", object: nil)
通知を受け取る(取得)
NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(YourClassName.methodOfReceivedNotification(_:)), name:"NotificationIdentifier", object: nil)
受信した通知のメソッドハンドラ
func methodOfReceivedNotification(notification: NSNotification){
// Take Action on Notification
}
歴史的なXcodeバージョンの場合...
通知を送信(ポスト)
NSNotificationCenter.defaultCenter().postNotificationName("NotificationIdentifier", object: nil)
通知を受け取る(取得)
NSNotificationCenter.defaultCenter().addObserver(self, selector: "methodOfReceivedNotification:", name:"NotificationIdentifier", object: nil)
通知を削除します
NSNotificationCenter.defaultCenter().removeObserver(self, name: "NotificationIdentifier", object: nil)
NSNotificationCenter.defaultCenter().removeObserver(self) // Remove from all notifications being observed
受信した通知のメソッドハンドラ
func methodOfReceivedNotification(notification: NSNotification) {
// Take Action on Notification
}
クラスまたはターゲットメソッドに@objcで注釈を付ける
@objc private func methodOfReceivedNotification(notification: NSNotification) {
// Take Action on Notification
}
// Or
dynamic private func methodOfReceivedNotification(notification: NSNotification) {
// Take Action on Notification
}
NotificationCenterの場合と同様に、Swift 3.0は多くの "文字列型"のAPIをstruct
"ラッパー型"に置き換えました。通知はString
ではなくstruct Notfication.Name
によって識別されるようになりました。 Swift 3への移行ガイド を参照してください。
前の 用法:
// Define identifier
let notificationIdentifier: String = "NotificationIdentifier"
// Register to receive notification
NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(YourClassName.methodOfReceivedNotification(_:)), name: notificationIdentifier, object: nil)
// Post a notification
NSNotificationCenter.defaultCenter().postNotificationName(notificationIdentifier, object: nil)
新しいSwift 3.0の使い方
// Define identifier
let notificationName = Notification.Name("NotificationIdentifier")
// Register to receive notification
NotificationCenter.default.addObserver(self, selector: #selector(YourClassName.methodOfReceivedNotification), name: notificationName, object: nil)
// Post notification
NotificationCenter.default.post(name: notificationName, object: nil)
すべてのシステム通知タイプがNotification.Name
の静的定数として定義されました。すなわち.UIDeviceBatteryLevelDidChange
、.UIApplicationDidFinishLaunching
、.UITextFieldTextDidChange
など.
システム通知との整合性を保つために、独自のカスタム通知を使ってNotification.Name
を拡張することができます。
// Definition:
extension Notification.Name {
static let yourCustomNotificationName = Notification.Name("yourCustomNotificationName")
}
// Usage:
NotificationCenter.default.post(name: .yourCustomNotificationName, object: nil)
これを行うための良い方法は、Objective-Cコードからよく使用される addObserver(forName:object:queue:using:)
メソッドではなく、 addObserver(_:selector:name:object:)
メソッドを使用することです。最初のバリエーションの利点は、メソッドに@objc
属性を使用する必要がないということです。
func batteryLevelChanged(notification: Notification) {
// do something useful with this information
}
let observer = NotificationCenter.default.addObserver(
forName: NSNotification.Name.UIDeviceBatteryLevelDidChange,
object: nil, queue: nil,
using: batteryLevelChanged)
また、必要に応じて、メソッドの代わりにクロージャを使用することもできます。
let observer = NotificationCenter.default.addObserver(
forName: NSNotification.Name.UIDeviceBatteryLevelDidChange,
object: nil, queue: nil) { _ in print("????") }
戻り値を使用して、後で通知を受け取るのをやめることができます。
NotificationCenter.default.removeObserver(observer)
このメソッドを使用することにはもう1つの利点がありました。これは、コンパイラによって静的にチェックできないセレクタ文字列を使用する必要がないため、メソッドの名前を変更しても壊れにくいためです。後でその問題を修正する #selector
式 を含めてください。
通知名を宣言する
extension Notification.Name {
static let purchaseDidFinish = Notification.Name("purchaseDidFinish")
}
オブザーバを追加する方法は2つあります。
Selector
を使う
NotificationCenter.default.addObserver(self, selector: #selector(myFunction), name: .purchaseDidFinish, object: nil)
@objc func myFunction(notificaiont: Notification) {
print(notificaiont.object ?? "") //myObject
print(notificaiont.userInfo ?? "") //[AnyHashable("key"): "Value"]
}
あるいはblock
を使う
NotificationCenter.default.addObserver(forName: .purchaseDidFinish, object: nil, queue: nil) { [weak self] (notification) in
guard let strongSelf = self else {
return
}
strongSelf.myFunction(notificaiont: notification)
}
func myFunction(notificaiont: Notification) {
print(notificaiont.object ?? "") //myObject
print(notificaiont.userInfo ?? "") //[AnyHashable("key"): "Value"]
}
あなたの通知を投稿
NotificationCenter.default.post(name: .purchaseDidFinish, object: "myObject", userInfo: ["key": "Value"])
iOS 9およびOS X 10.11から。 NSNotificationCenterオブザーバは、割り当て解除時に登録解除する必要がなくなりました。 詳細情報
block
ベースの実装では、ブロック内でself
を使用したい場合は、弱い - 強いダンスをする必要があります。 詳細情報
NSNotificationCenterを使用してデータを渡す
Swift 3.0ではNotificationCentreを、Swift 2.0ではNSNotificationCenterを使用してデータを渡すこともできます。
Swift 2.0バージョン
[NSObject:AnyObject]型のオプションのディクショナリであるuserInfoを使用して情報を渡しますか?
let imageDataDict:[String: UIImage] = ["image": image]
// Post a notification
NSNotificationCenter.defaultCenter().postNotificationName(notificationName, object: nil, userInfo: imageDataDict)
// Register to receive notification in your class
NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(self.showSpinningWheel(_:)), name: notificationName, object: nil)
// handle notification
func showSpinningWheel(notification: NSNotification) {
if let image = notification.userInfo?["image"] as? UIImage {
// do something with your image
}
}
Swift 3.0バージョン
UserInfoは[AnyHashable:Any]を取りますか?引数として、Swiftでは辞書リテラルとして提供しています。
let imageDataDict:[String: UIImage] = ["image": image]
// post a notification
NotificationCenter.default.post(name: NSNotification.Name(rawValue: "notificationName"), object: nil, userInfo: imageDataDict)
// `default` is now a property, not a method call
// Register to receive notification in your class
NotificationCenter.default.addObserver(self, selector: #selector(self.showSpinningWheel(_:)), name: NSNotification.Name(rawValue: "notificationName"), object: nil)
// handle notification
func showSpinningWheel(_ notification: NSNotification) {
if let image = notification.userInfo?["image"] as? UIImage {
// do something with your image
}
}
ソース NotificationCentre(Swift 3.0)およびNSNotificationCenter(Swift 2.0)を使用してデータを渡す
通知も削除する必要があります。
例.
deinit
{
NotificationCenter.default.removeObserver(self, name:NSNotification.Name(rawValue: "notify"), object: nil)
}
次のいずれかを実行して、セレクタ - @objcで注釈を付けずに)を正常に使用できます。
NSNotificationCenter.defaultCenter().addObserver(self,
selector:"batteryLevelChanged:" as Selector,
name:"UIDeviceBatteryLevelDidChangeNotification",
object:nil)
OR
let notificationSelector: Selector = "batteryLevelChanged:"
NSNotificationCenter.defaultCenter().addObserver(self,
selector: notificationSelector,
name:"UIDeviceBatteryLevelDidChangeNotification",
object:nil)
私のxcrunバージョンはSwift 1.2を示していて、これはXcode 6.4とXcode 7 beta 2(私はSwift 2.0を使うだろうと思った)で動作します。
$xcrun Swift --version
Apple Swift version 1.2 (swiftlang-602.0.53.1 clang-602.0.53)
Swift 2.2 - XCode 7.3では、NSNotificationCenter
に#selector
を使用しています
NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(rotate), name: UIDeviceOrientationDidChangeNotification, object: nil)
NSNotificationCenterSwift 4.0にiOS 11にオブザーバ構文を追加
NotificationCenter.default.addObserver(self, selector: #selector(keyboardShow), name: NSNotification.Name.UIKeyboardWillShow, object: nil)
これは、keyboardWillShow通知名タイプ用です。利用可能なオプションから他のタイプを選択できます
selectorは、キーボードがどのように表示されるかを処理する@objc func型です(これはあなたのユーザー関数です)。
In - Swift 5
ViewControllerBからViewControllerAにデータを受信したいとしましょう
ViewControllerA(受信機)
import UIKit
class ViewControllerA: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
//MARK: - - - - - Code for Passing Data through Notification Observer - - - - -
// add observer in controller(s) where you want to receive data
NotificationCenter.default.addObserver(self, selector: #selector(self.methodOfReceivedNotification(notification:)), name: Notification.Name("NotificationIdentifier"), object: nil)
}
//MARK: - - - - - Method for receiving Data through Post Notificaiton - - - - -
@objc func methodOfReceivedNotification(notification: Notification) {
print("Value of notification : ", notification.object ?? "")
}
}
ViewControllerB(送信者)
import UIKit
class ViewControllerB: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
//MARK: - - - - - Set data for Passing Data Post Notification - - - - -
let objToBeSent = "Test Message from Notification"
NotificationCenter.default.post(name: Notification.Name("NotificationIdentifier"), object: objToBeSent)
}
}
Swift 3、Xcode 8.2: - バッテリー状態レベルの確認
//Add observer
NotificationCenter.default.addObserver(self, selector: #selector(batteryStateDidChange), name: NSNotification.Name.UIDeviceBatteryStateDidChange, object: nil)
//Fired when battery level changes
func batteryStateDidChange(notification: NSNotification){
//perform manipulation here
}
Swift 5&Xcode 10.2:
NotificationCenter.default.addObserver(
self,
selector: #selector(batteryLevelDidChangeNotification),
name: UIDevice.batteryLevelDidChangeNotification,
object: nil)