Something went wrong. Try again.
This repository has no description
Something went wrong. Try again.
4.8 kB · 142 lines
Swift
at main
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143import ComposableArchitecture2import Foundationimport Tagged
/// A source whose content can change independently of notification delivery.////// The notification package treats both the identifier and version as opaque values. A consuming/// application decides what the source represents, how versions compare, and what should reload.public struct NotificationSource: Equatable, Hashable, Sendable { public enum IDTag {} public enum VersionTag {}
public typealias ID = Tagged<IDTag, String> public typealias Version = Tagged<VersionTag, String>
public var id: ID public var version: Version
public init(id: ID, version: Version) { self.id = id self.version = version }}
/// An application-owned route with a stable provider-compatible string representation.public protocol NotificationRoute: Equatable, Sendable { init?(notificationRoute: String) var notificationRoute: String { get }}
/// Provider-independent text displayed when a notification is visible to the user.public struct NotificationPresentation: Equatable, Sendable { /// How urgently providers and operating systems should present visible content. public enum Delivery: Equatable, Sendable { case standard
/// A time-bounded alert that may use platform emergency-notification affordances. case emergency(expiresAt: Date) }
public var body: String public var delivery: Delivery public var title: String
public init( title: String, body: String, delivery: Delivery = .standard ) { self.body = body self.delivery = delivery self.title = title }}
/// Source-backed application content addressed by an application-owned route.public struct NotificationContent<Route: NotificationRoute>: Equatable, Sendable { public var presentation: NotificationPresentation? public var route: Route public var source: NotificationSource
public init( source: NotificationSource, route: Route, presentation: NotificationPresentation? = nil ) { self.presentation = presentation self.route = route self.source = source }}
/// A provider-independent notification message decoded for one application route type.public enum NotificationMessage<Route: NotificationRoute>: Equatable, Sendable { case content(NotificationContent<Route>) case sourceAvailable(NotificationSource)}
/// A request for notification signals about one source.public struct NotificationSubscription: Equatable, Hashable, Sendable { public var sourceID: NotificationSource.ID
public init(sourceID: NotificationSource.ID) { self.sourceID = sourceID }}
/// A transport-independent signal delivered to the application feature tree.public enum NotificationSignal: Equatable, Hashable, Sendable { case sourceAvailable(NotificationSource)}
/// Collects the notification subscriptions published by mounted descendant features.public enum NotificationSubscriptionsPreferenceKey: FeaturePreferenceKey { public static let defaultValue: Set<NotificationSubscription> = []
public static func reduce( value: inout Set<NotificationSubscription>, nextValue: () -> Set<NotificationSubscription> ) { value.formUnion(nextValue()) }}
extension FeatureProtocol { /// Publishes the sources for which this feature wants notification signals. public func notificationSubscriptions( _ subscriptions: Set<NotificationSubscription> ) -> some Feature { self.preference( key: NotificationSubscriptionsPreferenceKey.self, value: subscriptions ) }
/// Publishes sources derived from the feature's mounted state. /// /// Use this overload when the desired subscriptions belong to feature state. The modifier's /// feature store is installed before its body reads the key path, so callers do not need to /// capture their feature store while composing `body`. public func notificationSubscriptions( _ subscriptions: KeyPath<State, Set<NotificationSubscription>> ) -> some Feature { self.modifier( NotificationSubscriptionsModifier<State, Action>( subscriptions: subscriptions ) ) }}
private struct NotificationSubscriptionsModifier<State, Action>: FeatureModifier { let subscriptions: KeyPath<State, Set<NotificationSubscription>> let store = FeatureStore<State, Action>()
func body(content: Content) -> some FeatureProtocol<State, Action> { content.preference( key: NotificationSubscriptionsPreferenceKey.self, value: store.state[keyPath: subscriptions] ) }}