DropletID
Stable identifier of a droplet across the whole system.
struct DropletID
The same string appears in three places and must match in all of them: the DroppyDropletID key of the bundle's Info.plist, the id field of the store manifest entry, and the Droplet.id static property of the runtime object. The loader refuses bundles where these disagree.
Use a short, lowercase, url-safe string, for example "worldclock".
The string is not only an identifier. The host builds a filesystem path component from it (~/Library/Application Support/Droppy/Droplets/<id>/) and a preference key prefix (droplet.<id>.), which makes an unchecked id a path-traversal and namespace-collision hazard. isValid(_:) is the charset that closes both, and DropletBundleInfo refuses a bundle whose plist id fails it, before any of that bundle's code is loaded.
Initializers
init(_:)
init(_ rawValue: String)
Creates an identifier from a raw string.
init(from:)
init(from decoder: Decoder) throws
init(rawValue:)
init(rawValue: String)
Creates an identifier from a raw string.
init(stringLiteral:)
init(stringLiteral value: String)
String-literal convenience, so static let id: DropletID = "worldclock" reads naturally.
init(validating:)
init?(validating rawValue: String)
Creates an identifier, returning nil when rawValue is not a valid droplet id.
The unlabelled and rawValue: initializers stay unchecked on purpose: they are how a host reconstructs an id it already trusts, and how a droplet writes its own static let id literal. Use this one for anything that came from outside the process.
Type properties
validLengthRange
static let validLengthRange: ClosedRange<Int>
Length bounds a droplet id must fall inside, inclusive.
Properties
description
var description: String { get }
isValid
var isValid: Bool { get }
Whether this identifier satisfies isValid(_:).
rawValue
let rawValue: String
The raw string value of the identifier.
Type methods
isValid(_:)
static func isValid(_ rawValue: String) -> Bool
Whether rawValue is a usable droplet id.
The rule: 3 to 40 characters, ASCII letters, digits and hyphens only, starting with a letter and ending with a letter or digit. That rejects every character that could turn an id into something other than one path component or one preference namespace:
/and\and..cannot appear, so an id can never escape the directory the host builds for it..cannot appear, sodroplet.<id>.<key>has exactly one meaning. Without that rule, dropletawriting keyb.cand dropleta.bwriting keycare the same default.- No spaces, no leading or trailing hyphen, no empty string.
Uppercase ASCII letters are accepted because in-tree droplets shipped with camelCase ids before this rule existed. The store's submission intake is deliberately stricter and requires lowercase; this function is the safety floor that runs on the user's machine, not the style rule for new public submissions. Hosts comparing ids for uniqueness should fold case, because the id becomes a path component and macOS filesystems are usually case-insensitive.
Methods
encode(to:)
func encode(to encoder: Encoder) throws