DropletHost
Everything the host offers a droplet.
@MainActor struct DropletHost
A droplet receives one of these in activate(host:) and should store it. There is no global accessor and no singleton: if you did not keep the host, you cannot reach the host, which is deliberate. It keeps a droplet's dependencies visible in its own source and lets the harness hand you a different implementation without changing a line of droplet code.
Capabilities
Services are present whether or not the droplet is allowed to use them, but the effect is gated: a call the droplet lacks the capability for returns false, nil, or does nothing, and the host logs the refusal. Check isGranted(_:) when you want to hide UI for something you cannot do, rather than offering a button that will quietly fail.
Declare the capabilities you need in droplet.json; the store shows them to the user before they install.
final class WorldClockDroplet: Droplet, ShelfWidgetProviding {
static let id: DropletID = "worldclock"
private var host: DropletHost?
func activate(host: DropletHost) throws {
self.host = host
let zone = host.preferences.value(forKey: "zone", default: "UTC")
host.log.info("activated for \(zone)")
}
func deactivate() { host = nil }
}Initializers
init(grantedCapabilities:preferences:environment:log:installState:hud:shelf:liveActivity:notchSurface:shortcuts:workspace:feedback:permissions:)
@MainActor init(grantedCapabilities: Set<DropletPermission>, preferences: any DropletPreferencesService, environment: any DropletEnvironmentService, log: any DropletLogService, installState: any DropletInstallStateService, hud: any DropletHUDService, shelf: any DropletShelfService, liveActivity: any DropletLiveActivityService, notchSurface: any DropletNotchSurfaceService, shortcuts: any DropletShortcutsService, workspace: any DropletWorkspaceService, feedback: any DropletFeedbackService, permissions: any DropletPermissionsService)
Creates a host. Implemented by Droppy and by DroppyKitHarness; droplets never call this.
Properties
environment
@MainActor let environment: any DropletEnvironmentService
Read-only facts about the host and the machine.
feedback
@MainActor let feedback: any DropletFeedbackService
Droppy's own sound and haptic cues.
grantedCapabilities
@MainActor let grantedCapabilities: Set<DropletPermission>
The capabilities the user granted this droplet at install time.
hud
@MainActor let hud: any DropletHUDService
Transient HUDs on the notch surface. Requires hud.
installState
@MainActor let installState: any DropletInstallStateService
Which of this droplet's pieces the user has switched on.
liveActivity
@MainActor let liveActivity: any DropletLiveActivityService
The seat this droplet's live activity currently holds.
log
@MainActor let log: any DropletLogService
Droppy's own log stream, tagged with your droplet id.
notchSurface
@MainActor let notchSurface: any DropletNotchSurfaceService
Expanded (takeover) surfaces. Requires expanded-surface.
permissions
@MainActor let permissions: any DropletPermissionsService
Checking and requesting macOS permissions.
preferences
@MainActor let preferences: any DropletPreferencesService
Persistent, droplet-scoped settings.
shelf
@MainActor let shelf: any DropletShelfService
Opening, closing, and re-measuring the shelf. Requires shelf-read to observe and shelf-write to act.
shortcuts
@MainActor let shortcuts: any DropletShortcutsService
Global keyboard shortcuts. Requires global-shortcuts.
workspace
@MainActor let workspace: any DropletWorkspaceService
Opening URLs and files, and writing the pasteboard.
Methods
isGranted(_:)
@MainActor func isGranted(_ capability: DropletPermission) -> Bool
Whether the user granted a capability.
Use it to hide affordances you cannot honour, not as a substitute for handling a refusal: capabilities can be revoked while the droplet runs.