-
Notifications
You must be signed in to change notification settings - Fork 7
feat: add supplemental activity families support for iOS 18+ #13
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
feat: add supplemental activity families support for iOS 18+ #13
Conversation
- Add renderer tests for supplemental.small variant serialization - Add plugin tests for validation and widget bundle generation - Add WatchLiveActivity example demonstrating supplemental.small - Enable supplementalFamilies in example app config
Swift syntax requires @unknown default to be its own case, cannot combine with other patterns.
- Add comprehensive guide at development/supplemental-activity-families.md - Update plugin-configuration.md with liveActivity config section - Add navigation entry in development/_meta.json - Reference supplemental families in developing-live-activities.md
|
@mrevanzak is attempting to deploy a commit to the Callstack Team on Vercel. A member of the Team first needs to authorize it. |
|
closed #11 |
|
crazy that Opus did this in one shot 🤯 |
|
I'm going to go through it tomorrow! 👀 |
Align API naming with Apple's native .supplementalActivityFamilies() modifier. Changes: - TypeScript: supplemental -> supplementalActivityFamilies in variants - Plugin config: supplementalFamilies -> supplementalActivityFamilies - Swift: supplementalSmall -> supplementalActivityFamiliesSmall - JSON key: sup_sm -> saf_sm - Generated Swift wrapper: VoltraWidgetWithSupplementalActivityFamilies - Update all tests and documentation
dca490f to
1ac4a0a
Compare
| /// A view that adapts its content based on the activity family environment | ||
| /// - For .small (watchOS/CarPlay): Uses supplementalActivityFamiliesSmall content if available, falls back to lockScreen | ||
| /// - For .medium (iPhone lock screen) and unknown: Always uses lockScreen |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now I understand this better. Apple’s docs aren't very clear about what behavior to expect 👌
| * Supported supplemental activity families (iOS 18+) | ||
| * These enable Live Activities to appear on watchOS Smart Stack and CarPlay | ||
| */ | ||
| export type ActivityFamily = 'small' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What about 'medium'?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
medium is the default one that we have without any config @V3RON. the lockscreen one. so no need to specify it again. Even if we pass [.small, .medium], it will have the same effect as [.small].
| Starting with iOS 18, Live Activities can appear on additional surfaces beyond the iPhone lock screen and Dynamic Island: | ||
|
|
||
| - **watchOS Smart Stack** (iOS 18+) - Appears on paired Apple Watch | ||
| - **CarPlay Dashboard** (iOS 26+) - Appears on CarPlay displays |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is CarPlay somehow connected to supplemental activity families? I think it just works with the default configuration.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm going to verify this in my car later today 👀
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
alright haha
| function generateVoltraWidgetWrapper(familiesSwift: string): string { | ||
| return dedent` | ||
| // MARK: - Live Activity with Supplemental Activity Families | ||
| struct VoltraWidgetWithSupplementalActivityFamilies: Widget { | ||
| private let wrapped = VoltraWidget() | ||
| var body: some WidgetConfiguration { | ||
| if #available(iOS 18.0, *) { | ||
| return wrapped.body.supplementalActivityFamilies([${familiesSwift}]) | ||
| } else { | ||
| return wrapped.body | ||
| } | ||
| } | ||
| } | ||
| ` | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note for myself: make sure to format generated code correctly, so it's more pleasant to read.
|
There may be cases where we want to enable Watch only for a subset of Live Activities. In the current implementation, it's either none or all-in. I'm wondering if we should refactor this so we have two configs for Live Activities: one for "non-Watch" and another for "Watch-enabled". We could then target one of them based on the config parameter the user passes when displaying the Live Activity. This would also work remotely. WDYT? |
so how is the code on react native gonna be? |
|
We would accept supplementalActivityFamilies in startLiveActivity, and based on its value we would use a different Activity on the Swift side, switching from DefaultVoltraLiveActivityAttributes (currently VoltraAttributes) to WatchVoltraLiveActivityAttributes. I’m not sure whether it’s legitimate to change the attributes type during the lifetime of an activity, but I guess we’ll find out in practice. |
just dont supply it into supplementalActivityFamilies object when start those? |
|
or if you mean that you dont want certain variant to be not shown on watch at all then yeah we need to adjust it |

Summary
supplementalActivityFamiliesmodifier (iOS 18+) enabling Live Activities on watchOS Smart Stack and CarPlaysupplementalActivityFamilies.smallvariant in TypeScript API with automatic fallback tolockScreencontentliveActivity.supplementalActivityFamilies: ["small"]Changes
TypeScript
supplementalActivityFamilies.smalltoLiveActivityVariantstypesup_smJSON key to renderer outputSwift
supplementalSmallcase toVoltraRegionenumVoltraAdaptiveLockScreenViewwith@Environment(\.activityFamily)detectionPlugin
LiveActivityConfigtype withsupplementalActivityFamiliesoptionVoltraWidgetWithSupplementalActivityFamilieswrapper when configuredUsage
{ "expo": { "plugins": [ ["voltra", { "groupIdentifier": "group.com.example", "liveActivity": { "supplementalActivityFamilies": ["small"] } }] ] } }Requirements
Example