Skip to content

ProtocolFoundationEssentials

NotificationCenter.AsyncMessage

iOS 26.0+ iPadOS 26.0+ Mac Catalyst 26.0+ macOS 26.0+ tvOS 26.0+ visionOS 26.0+ watchOS 26.0+
A protocol for creating types that you can post to a notification center, which posts them to an arbitrary isolation.
protocol AsyncMessage : Sendable

Overview

You post types conforming to AsyncMessage to a notification center using post(_:subject:) and observe them with addObserver(of:for:using:).

The notification center delivers AsyncMessage types asynchronously when posted. Asynchronous delivery isn’t suitable for messages with time-critical deliveries, such as a message that must have its observers called before a certain action takes place.

For types that post on the main actor, use NotificationCenter.MainActorMessage.

Each AsyncMessage is associated with a specific Subject type.

For example, an AsyncMessage associated with the type Event could use the following declaration:

struct EventDidStart: NotificationCenter.AsyncMessage {
    typealias Subject = Event
}

AsyncMessage can use an optional NotificationCenter.MessageIdentifier type for context-aware observer registration:

extension NotificationCenter.MessageIdentifier where Self == NotificationCenter.BaseMessageIdentifier<EventDidStart> {
    static var didStart: Self { .init() }
}

With this identifier, observers can receive information about a specific instance by registering for this message with a NotificationCenter:

let observerToken = NotificationCenter.default.addObserver(of: importantEvent, for: .didStart)

Or an observer can receive information about any instance with:

let observerToken = NotificationCenter.default.addObserver(of: Event.self, for: .didStart)

The notification center ties observation the lifetime of the returned NotificationCenter.ObservationToken and automatically de-registers the observer if the token goes out of scope. You can also remove observation explicitly:

NotificationCenter.default.removeObserver(observerToken)

Notification Interoperability

AsyncMessage includes optional interoperability with Notification, enabling posters and observers of both types to pass information.

It does this by offering a makeMessage(_:) method that collects values from a Notification‘s Notification/userInfo and populates properties on a new message. In the other direction, a makeNotification(_:) method collects the message’s defined properties and loads them into a new notification’s Notification/userInfo dictionary.

For example, if there exists a Notification posted on an arbitrary isolation identified by the Notification/Name "eventDidFinish" with a Notification/userInfo dictionary containing the key "duration" as an NSNumber, an app could post and observe the notification with the following NotificationCenter.AsyncMessage:

struct EventDidFinish: NotificationCenter.AsyncMessage {
    typealias Subject = Event
    static var name: Notification.Name { Notification.Name("eventDidFinish") }

    var duration: Int

    static func makeNotification(_ message: Self) -> Notification {
        return Notification(name: Self.name, userInfo: ["duration": NSNumber(message.duration)])
    }

    static func makeMessage(_ notification: Notification) -> Self? {
        guard let userInfo = notification.userInfo,
              let duration = userInfo["duration"] as? Int
        else {
            return nil
        }

        return Self(duration: duration)
    }
}

With this definition, an observer for this AsyncMessage type receives information even if the poster used the Notification equivalent, and vice versa.

Topics

Associated Types

Relationships

Inherits From

  • Swift.Sendable
  • Swift.SendableMetatype