462 Stimmen

NSNotificationCenter addObserver in Swift

Wie fügt man in Swift einen Beobachter zum Standard-Benachrichtigungscenter hinzu? Ich versuche diese Codezeile zu übertragen, die eine Benachrichtigung sendet, wenn sich der Batteriestand ändert.

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

843voto

Renish Dadhaniya Punkte 10462

Swift 4.0 & Xcode 9.0+:

Nachricht senden (posten):

NotificationCenter.default.post(name: Notification.Name("NotificationIdentifier"), object: nil)

ODER

NotificationCenter.default.post(name: Notification.Name("NotificationIdentifier"), object: nil, userInfo: ["Renish":"Dadhaniya"])

Nachricht erhalten (abrufen):

NotificationCenter.default.addObserver(self, selector: #selector(self.methodOfReceivedNotification(notification:)), name: Notification.Name("NotificationIdentifier"), object: nil)

Funktion-Methode-Handler für erhaltene Benachrichtigung:

@objc func methodOfReceivedNotification(notification: Notification) {}

Swift 3.0 & Xcode 8.0+:

Nachricht senden (posten):

NotificationCenter.default.post(name: Notification.Name("NotificationIdentifier"), object: nil)

Nachricht erhalten (abrufen):

NotificationCenter.default.addObserver(self, selector: #selector(YourClassName.methodOfReceivedNotification(notification:)), name: Notification.Name("NotificationIdentifier"), object: nil)

Methodenhandler für erhaltene Benachrichtigung:

func methodOfReceivedNotification(notification: Notification) {
  // Aktion bei Benachrichtigung ausführen
}

Benachrichtigung entfernen:

deinit {
  NotificationCenter.default.removeObserver(self, name: Notification.Name("NotificationIdentifier"), object: nil)
}

Swift 2.3 & Xcode 7:

Nachricht senden (posten)

NSNotificationCenter.defaultCenter().postNotificationName("NotificationIdentifier", object: nil)

Nachricht erhalten (abrufen)

NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(YourClassName.methodOfReceivedNotification(_:)), name:"NotificationIdentifier", object: nil)

Methodenhandler für erhaltene Benachrichtigung

func methodOfReceivedNotification(notification: NSNotification){
  // Aktion bei Benachrichtigung ausführen
}


Für historische Xcode Versionen...



Nachricht senden (posten)

NSNotificationCenter.defaultCenter().postNotificationName("NotificationIdentifier", object: nil)

Nachricht erhalten (abrufen)

NSNotificationCenter.defaultCenter().addObserver(self, selector: "methodOfReceivedNotification:", name:"NotificationIdentifier", object: nil)

Benachrichtigung entfernen

NSNotificationCenter.defaultCenter().removeObserver(self, name: "NotificationIdentifier", object: nil)
NSNotificationCenter.defaultCenter().removeObserver(self) // Aus allen beobachteten Benachrichtigungen entfernen

Methodenhandler für erhaltene Benachrichtigung

func methodOfReceivedNotification(notification: NSNotification) {
  // Aktion bei Benachrichtigung ausführen
}

Klassen oder die Zielmethode mit @objc annotieren

@objc private func methodOfReceivedNotification(notification: NSNotification) {
  // Aktion bei Benachrichtigung ausführen
}

// Oder

dynamic private func methodOfReceivedNotification(notification: NSNotification) {
  // Aktion bei Benachrichtigung ausführen
}

475voto

Connor Punkte 62453

Es ist dasselbe wie die Objective-C-API, verwendet aber die Syntax von Swift.

Swift 4.2 & Swift 5:

NotificationCenter.default.addObserver(
    self,
    selector: #selector(self.batteryLevelChanged),
    name: UIDevice.batteryLevelDidChangeNotification,
    object: nil)

Wenn Ihr Beobachter nicht von einem Objective-C-Objekt erbt, müssen Sie Ihre Methode mit @objc voranstellen, um sie als Selector verwenden zu können.

@objc private func batteryLevelChanged(notification: NSNotification){     
    //tue etwas mit der userInfo-Eigenschaft des notification-Objekts
}

Siehe NSNotificationCenter Klassenreferenz, Interaktion mit Objective-C-APIs

61voto

Jon Colverson Punkte 2878

Ein schöner Weg, dies zu tun, ist die Verwendung der addObserver(forName:object:queue:using:)-Methode anstelle der addObserver(_:selector:name:object:)-Methode, die häufig aus Objective-C-Code verwendet wird. Der Vorteil der ersten Variante besteht darin, dass Sie nicht das @objc-Attribut auf Ihrer Methode verwenden müssen:

    func batteryLevelChanged(notification: Notification) {
        // Mach etwas Nützliches mit dieser Information
    }

    let observer = NotificationCenter.default.addObserver(
        forName: NSNotification.Name.UIDeviceBatteryLevelDidChange,
        object: nil, queue: nil,
        using: batteryLevelChanged)

und Sie können sogar einfach eine Closure anstelle einer Methode verwenden, wenn Sie möchten:

    let observer = NotificationCenter.default.addObserver(
        forName: NSNotification.Name.UIDeviceBatteryLevelDidChange,
        object: nil, queue: nil) { _ in print("") }

Sie können den zurückgegebenen Wert verwenden, um später das Abhören der Benachrichtigung zu stoppen:

    NotificationCenter.default.removeObserver(observer)

Es gab früher noch einen weiteren Vorteil bei der Verwendung dieser Methode, der darin bestand, dass Sie keine Selektorzeichenfolgen verwenden mussten, die vom Compiler nicht statisch überprüft werden konnten und daher anfällig für Fehler waren, wenn die Methode umbenannt wurde, aber Swift 2.2 und später enthalten #selector-Ausdrücke, die dieses Problem beheben.

52voto

Warif Akhand Rishi Punkte 23036
  1. Benennen Sie eine Benachrichtigung

    extension Notification.Name {
        static let purchaseDidFinish = Notification.Name("purchaseDidFinish")
    }
  2. Sie können den Beobachter auf zwei Arten hinzufügen:

    Verwenden von Selector

    NotificationCenter.default.addObserver(self, selector: #selector(myFunction), name: .purchaseDidFinish, object: nil)
    
    @objc func myFunction(notification: Notification) {
        print(notification.object ?? "") //myObject
        print(notification.userInfo ?? "") //[AnyHashable("key"): "Value"]
    }

    oder Verwenden von block

    NotificationCenter.default.addObserver(forName: .purchaseDidFinish, object: nil, queue: nil) { [weak self] (notification) in
        guard let strongSelf = self else {
            return
        }
    
        strongSelf.myFunction(notification: notification)
    }
    
    func myFunction(notification: Notification) {
        print(notification.object ?? "") //myObject
        print(notification.userInfo ?? "") //[AnyHashable("key"): "Value"]
    }
  3. Versenden Sie Ihre Benachrichtigung

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

ab iOS 9 und OS X 10.11. Es ist nicht mehr notwendig, dass ein NSNotificationCenter-Beobachter sich selbst abmeldet, wenn er dealloziert wird. mehr Info

Für eine Implementierung auf Basis von block müssen Sie einen Weak-Strong-Tanz ausführen, wenn Sie self im Block verwenden möchten. mehr Info

Blockbasierte Beobachter müssen entfernt werden mehr Info

let center = NSNotificationCenter.defaultCenter()
center.removeObserver(self.localeChangeObserver)

41voto

Jeffrey Fulton Punkte 4146

Swift 3.0 in Xcode 8

Swift 3.0 hat viele "stringly-typed" APIs durch struct "Wrapper-Typen" ersetzt, wie im Fall von NotificationCenter. Benachrichtigungen werden jetzt durch einen struct Notfication.Name identifiziert anstelle von String. Siehe den Umstieg auf Swift 3-Leitfaden.

Vorherige Verwendung:

// Identifier definieren
let notificationIdentifier: String = "NotificationIdentifier"

// Registrierung zum Empfang von Benachrichtigungen
NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(YourClassName.methodOfReceivedNotification(_:)), name: notificationIdentifier, object: nil)

// Benachrichtigung veröffentlichen
NSNotificationCenter.defaultCenter().postNotificationName(notificationIdentifier, object: nil)

Neue Swift 3.0 Verwendung:

// Identifier definieren
let notificationName = Notification.Name("NotificationIdentifier")

// Registrierung zum Empfang von Benachrichtigungen
NotificationCenter.default.addObserver(self, selector: #selector(YourClassName.methodOfReceivedNotification), name: notificationName, object: nil)

// Benachrichtigung veröffentlichen
NotificationCenter.default.post(name: notificationName, object: nil)

Alle Systembenachrichtigungstypen sind jetzt als statische Konstanten auf Notification.Name definiert; z.B. .UIDeviceBatteryLevelDidChange, .UIApplicationDidFinishLaunching, .UITextFieldTextDidChange, etc.

Sie können Notification.Name mit Ihren eigenen benutzerdefinierten Benachrichtigungen erweitern, um konsistent mit den Systembenachrichtigungen zu bleiben:

// Definition:
extension Notification.Name {
    static let yourCustomNotificationName = Notification.Name("yourCustomNotificationName")
}

// Verwendung:
NotificationCenter.default.post(name: .yourCustomNotificationName, object: nil)

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X