Notification Center - wurzelsand/swift-memos GitHub Wiki

Notification Center

Aufgabe 1: Observer

Füge dem NotificationCenter einen Observer einer Notification namens MyNotification hinzu. Dieser Observer soll mit der Ausgabe einer Bildschirmnachricht (print("Notification received!")) auf ein Posting reagieren.

Ausführung

import Foundation

let myNotification = Notification.Name("MyNotification")
let notificationCenter = NotificationCenter.default

let observer = notificationCenter.addObserver(forName: myNotification,
                                              object: nil,
                                              queue: nil) { notification in
    print("Notification received!")
}

notificationCenter.post(name: myNotification, object: nil)
notificationCenter.removeObserver(observer)

Ausgabe:

Notification received!

Aufgabe 2: Publisher und Subscription

Ändere die Ausführung aus Aufgabe 1 so um, dass ein Publisher für NotificationCenter entsteht, der myNotification posten kann. Der Publisher soll außerdem ein Sink erzeugen, welches auf das Posting einer Notification mit einer Bildschirmnachricht reagiert. Das Sink soll als Subscription (AnyCancellable) gespeichert werden.

Ausführung

import Foundation

let myNotification = Notification.Name("MyNotification")
let notificationCenter = NotificationCenter.default

let publisher = notificationCenter.publisher(for: myNotification, object: nil)

let subscription = publisher.sink { notification in
    print("\(notification.name.rawValue) received.")
}

notificationCenter.post(name: myNotification, object: nil)
subscription.cancel()

Ausgabe:

MyNotification received.

Anmerkungen

  • Mir scheint, dass das NotificationCenter für jeden seiner möglichen Notifications einen eigenen Publisher als Ausgang benötigt, um an diesen ein Sink "befestigen" zu können.

  • subscription.cancel() wird auch automatisch aufgerufen, wenn subscription freigegeben (deallocate) wird.

Aufgabe 3: Publisher und assign

Ich will NotificationCenter durch eine eigene Klasse ersetzen, die über didSet eine empfangene Nachricht ausgibt:

class MyNotificationCenter {
    var notification = "default" {
        didSet {
            print(notification)
        }
    }
}

Ausführung

import Foundation

class MyNotificationCenter {
    var notification = "default" {
        didSet {
            print(notification)
        }
    }
}

let notificationCenter = MyNotificationCenter()

let publisher = ["MyNotification"].publisher

let cancellable = publisher.assign(to: \.notification, on: notificationCenter)

Ausgabe:

MyNotification

Aufgabe 4: Publish, assign und erneut veröffentlichen

Ändere die Eigenschaft notification so um, dass sie mit Hilfe von assign und der Schreibweise $notification zu einem Publisher wird.

Ausführung

import Foundation

class MyNotificationCenter {
    @Published var notification = "default"
}

let notificationCenter = MyNotificationCenter()

let publisher = ["MyNotification"].publisher
publisher.assign(to: &notificationCenter.$notification)

let cancellable = notificationCenter.$notification
    .sink {
        print($0)
    }

Ausgabe:

MyNotification

Ich habe nun zwei Publisher: Zum einen die Variable publisher die die Elemente des Arrays ("MyNotification") veröffentlicht und zum anderen notificationCenter.$notification der mit den Elementen von publisher gespeist wird und diese erneut veröffentlicht. Eine Subscription vom Typ AnyCancellable fängt die Elemente mit einer Art Trichter (sink) ein und gibt sie auf dem Bildschirm aus.