it-swarm.com.ru

NSNotificationCenter addObserver в Swift

Как добавить наблюдателя в Swift в центр уведомлений по умолчанию? Я пытаюсь портировать эту строку кода, которая отправляет уведомление при изменении уровня заряда батареи.

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(batteryLevelChanged:) name:UIDeviceBatteryLevelDidChangeNotification object:nil];
356
Berry Blue

Он такой же, как Objective-C API, но использует синтаксис Swift.

NSNotificationCenter.defaultCenter().addObserver(
    self,
    selector: #selector(batteryLevelChanged:),
    name: UIDeviceBatteryLevelDidChangeNotification,
    object: nil)

Swift 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
}

См. Справочник по классам NSNotificationCenter , Взаимодействие с API Objective-C

401
Connor

Swift 4.0 и Xcode 9.0+:

Отправить (отправить) уведомление:

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)

Обработчик метода-функции для полученного уведомления:

@objc func methodOfReceivedNotification(notification: Notification) {}

Swift 3.0 и Xcode 8.0+:

Отправить (отправить) уведомление:

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)
}

Swift 2.3 и Xcode 7:

Отправить (Post) уведомление

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 ...



Отправить (Post) уведомление

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
}
703
Renish Dadhaniya

Swift 3.0 в Xcode 8

Swift 3.0 заменил многие «строковые» API на struct «типы-оболочки», как в случае с NotificationCenter. Уведомления теперь идентифицируются с помощью struct Notfication.Name, а не String. См. Руководство по переходу на 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)
40
Jeffrey Fulton

Хороший способ сделать это - использовать метод addObserver(forName:object:queue:using:) вместо метода addObserver(_:selector:name:object:) , который часто используется в коде Objective-C. Преимущество первого варианта в том, что вам не нужно использовать атрибут @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)

Раньше у этого метода было еще одно преимущество, заключающееся в том, что он не требовал использования строк селектора, которые не могли быть статически проверены компилятором и поэтому были хрупкими для взлома, если метод был переименован, но Swift 2.2 и позже включите #selector выражения , которые решают эту проблему.

37
Jon Colverson
  1. Объявить имя уведомления

    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"]
    }
    
  3. Разместите ваше уведомление

    NotificationCenter.default.post(name: .purchaseDidFinish, object: "myObject", userInfo: ["key": "Value"])
    

от iOS 9 и OS X 10.11. Это больше не нужно для NSNotificationCenter обозреватель, чтобы отменить регистрацию, будучи перераспределена. больше информации

Для реализации, основанной на block, вам нужно сделать слабый сильный танец, если вы хотите использовать self внутри блока. больше информации

15
Warif Akhand Rishi

Передайте данные с помощью NSNotificationCenter

Вы также можете передавать данные с помощью NotificationCentre в Swift 3.0 и NSNotificationCenter в Swift 2.0.

Swift 2.0 версия

Передать информацию, используя userInfo, который является необязательным словарем типа [NSObject: AnyObject]?

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)

7
Sahil

Мы должны также удалить уведомление.

Ex.

deinit 
{
  NotificationCenter.default.removeObserver(self, name:NSNotification.Name(rawValue: "notify"), object: nil)

}
2
Pankaj Jangid

Я могу сделать одно из следующего, чтобы успешно использовать селектор - без аннотировать что-либо с @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)
2
leanne

В Swift 2.2 - XCode 7.3 мы используем #selector для NSNotificationCenter

 NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(rotate), name: UIDeviceOrientationDidChangeNotification, object: nil)
2
Deepak Thakur

In Swift 5

Допустим, если вы хотите получать данные из ViewControllerB в ViewControllerA

ViewControllerA (Receiver)

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)
    }

}
1
swiftBoy

В 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
    }
1
Dhruv

NSNotificationCenter добавить синтаксис наблюдателя в Swift 4.0 для iOS 11  

  NotificationCenter.default.addObserver(self, selector: #selector(keyboardShow), name: NSNotification.Name.UIKeyboardWillShow, object: nil)

Это для типа имени уведомления клавиатурыWillShow. Другой тип может быть выбран из доступного варианта 

селектор имеет тип @objc func, который управляет тем, как будет отображаться клавиатура (это ваша пользовательская функция)

0
Ashim Dahal

Swift 5 & Xcode 10.2:

NotificationCenter.default.addObserver(
            self,
            selector: #selector(batteryLevelDidChangeNotification),
            name: UIDevice.batteryLevelDidChangeNotification,
            object: nil)
0
David.Chu.ca