Beside the notch
A live activity is a compact row beside the notch, like Ledge's own volume or charging: a symbol, a few words and, if you want, a progress ring. Ledge's own activities always come first.
Showing an activity
Send the activities you have up. Each send replaces the last, and one you leave out is taken down:
AddOnSession.show(activities: [
LiveActivity("countdown", symbol: "timer", text: "4:59", progress: .fraction(0.2), importance: .high)
])
AddOnSession.show(activities: []) // take them all down| Field | What it is |
|---|---|
id | Stable while it's up, so Ledge updates it in place |
symbol | An SF Symbol name |
text | Up to 60 characters. Keep it to a few words or a number |
progress | .fraction(0…1) fills a ring that far, .indeterminate spins an arc, .done fills the ring. Nil draws none |
importance | .low, .normal, .high or .attention, against other add-ons' activities. .attention is for something to act on now, and lets the add-on open its page (0.13.0) |
lasts | Seconds it stays after this send, 1 to 600. Nil keeps it up until you take it down |
Where it goes
The centre beside the notch belongs to the most important activity up, and up to two more sit in side pills. Every add-on activity ranks below every one of Ledge's, so music, volume or a low battery always win the centre. Ledge tells you where each of yours is whenever that changes:
| Placement | Means |
|---|---|
center | Beside the notch |
side | In a side pill, next to something more important |
outranked | Up, but waiting: more important activities fill every place |
suppressed | The user turned off this add-on's activities on its settings page |
idle | Down: it ended, ran out its time, or you took it down |
duplicatesBuiltIn | Not shown while Ledge's own activity of the same kind is up. 0.13.0 |
stale | Stepped aside after saying the same thing for half an hour. 0.13.0 |
handlers.onActivityPlacement = { change in
if change.placement == .suppressed { await countdown.stopSendingActivities() }
}One of each thing
When your activity is something Ledge shows itself, say so with kind: .nowPlaying for a podcast or a song, .download or .recording. While Ledge's own of that kind is up, yours steps aside with duplicatesBuiltIn and comes back when Ledge's ends, so there are never two of the same thing beside the notch. A kind never wins a place. Leave it out for anything else.
LiveActivity("episode", symbol: "headphones", text: "12:40", kind: .nowPlaying,
accessibilityValue: "12 minutes 40 seconds left")accessibilityValue is what VoiceOver says for the activity when its text alone doesn't, like a time read as words. Up to 120 characters.
Rows that stop changing
A .high or .attention activity that says exactly the same thing for half an hour steps aside, placed stale, until you send something different. A build that moves or a countdown that ticks never goes stale. This applies to add-ons built with LedgeKit 0.13.0 or later; older ones hear outranked for either new placement.
Good manners
- Take an activity down as soon as it has nothing to say. One that's up for no reason pushes the user's own away.
- For something brief, like “Done”, set
lastsinstead of sending it and taking it down yourself. - While you're
suppressed, stop sending updates. When the user turns activities back on you're told, so send the current state then. - If something important ends while you're
outrankedorsuppressed, say so another way, such as withLedgeHost.notify.