BuzzKitUI gives you the screen; BuzzKit.preferences gives you the data if you would rather build it.
The drop-in screen
List and nothing else, so present it in a page, a sheet or a tab and give it its own title. It loads on appearance, supports pull to refresh, saves optimistically as the person flips a toggle, and reloads from the server when a save fails. A failed first load shows a “Try again” row instead of an empty screen.
Identify the subscriber before showing the screen. Preferences belong to the identified subscriber, and the screen works even when notification permission was denied, which is what lets someone fix their choices before granting permission.
Your own rows
Pass a row builder to keep the loading, saving and error handling while owning the look completely. The builder is handed the topic and aBinding<Bool> for the whole topic.
Your own data source
Hand the view its ownload and save for previews, tests or a backend that proxies BuzzKit. save applies one change and returns the full new list; saveChannel does the same for a single channel and falls back to save when you leave it out.
What the person sees
Topics arrive resolved: the full catalog, each with the user’s state per channel. The screen renders them in the order the server returns them, so a topic or a category added in the dashboard appears without an app update.
The multi-channel menu is part of the default row. A custom row builder gets the plain topic binding instead, since a custom row decides its own shape.
Building a custom screen
BuzzKit.preferences is the whole data layer. Every call is async throws and needs an identified subscriber.
set overloads return the full updated [BuzzKit.Topic], so a screen can render the server’s answer rather than guessing what changed. They are @discardableResult, so ignore the return when you do not need it.
A BuzzKit.Topic carries the slug, name, description, category, and channels as [BuzzKit.Channel: BuzzKit.ChannelPreference].
Group topics into sections the same way the drop-in screen does.
TopicGroup.group(_:) preserves first appearance order, so the dashboard’s ordering carries through to a custom screen too.
Next
Topics and preferences
Creating topics, channels, defaults and daily caps.
Identity
Identifying the subscriber these preferences belong to.
Push
Permission and device registration.
Sending messages
Sending to a topic, and how preferences filter the audience.