### Build and Run Example App Source: https://github.com/callstackincubator/voltra/blob/main/CONTRIBUTING.md Commands to build the plugin, install example dependencies, prebuild for iOS, and run the example app on iOS. ```sh # 1) Build the plugin npm run build:plugin # 2) Install example dependencies (cd example && npm install) # 3) Prebuild for iOS (cd example && npx expo prebuild -p ios) # 4) Run on iOS (cd example && npx expo run:ios) ``` -------------------------------- ### Install Dependencies Source: https://github.com/callstackincubator/voltra/blob/main/CONTRIBUTING.md Run this command to install all required project dependencies. ```bash npm install ``` -------------------------------- ### Receive Push-to-Start Tokens for Remote Launch Source: https://github.com/callstackincubator/voltra/blob/main/website/docs/v1/ios/development/server-side-updates.md Implement this listener to get tokens for starting Live Activities remotely. Send these tokens to your server to initiate new Live Activities via push notifications. ```tsx useEffect(() => { const subscription = addVoltraListener('activityPushToStartTokenReceived', ({ pushToStartToken, type }) => { // Send the token to your server for starting new Live Activities sendTokenToServer({ token: pushToStartToken, type: 'start', }) }) return () => { subscription.remove() } }, []) ``` -------------------------------- ### Example Custom Preview Layout XML Source: https://github.com/callstackincubator/voltra/blob/main/website/docs/v1/android/api/plugin-configuration.md An example of an XML layout file that can be used for custom widget previews. ```xml ``` -------------------------------- ### Install Voltra Client Packages Source: https://github.com/callstackincubator/voltra/blob/main/README.md Install the client package for each platform you need. This is a prerequisite for setting up Voltra. ```sh # iOS npm install @use-voltra/ios-client # Android npm install @use-voltra/android-client ``` -------------------------------- ### Install iOS Packages Source: https://github.com/callstackincubator/voltra/blob/main/website/docs/v2/getting-started/installation.mdx Use this command to install the necessary packages for iOS Live Activities and widgets. ```bash npm install @use-voltra/ios @use-voltra/ios-client ``` -------------------------------- ### Start Live Activity with Multiple Configuration Options Source: https://github.com/callstackincubator/voltra/blob/main/website/docs/v1/ios/api/configuration.md Combine various configuration options, including dismissalPolicy, staleDate, and relevanceScore, when starting a Live Activity for comprehensive control. ```typescript await startLiveActivity(variants, { dismissalPolicy: { after: 30 }, staleDate: Date.now() + 2 * 60 * 60 * 1000, // 2 hours relevanceScore: 0.7, }) ``` -------------------------------- ### Install Android Packages Source: https://github.com/callstackincubator/voltra/blob/main/website/docs/v2/getting-started/installation.mdx Use this command to install the necessary packages for Android Home Screen widgets and ongoing notifications. ```bash npm install @use-voltra/android @use-voltra/android-client ``` -------------------------------- ### Starting a Live Activity Source: https://github.com/callstackincubator/voltra/blob/main/website/docs/v2/ios/development/managing-live-activities-locally.md Use `startLiveActivity()` to create and display a new Live Activity with initial content and configuration. ```APIDOC ## startLiveActivity() ### Description Creates and displays a new Live Activity. ### Method `startLiveActivity(variants, options)` ### Parameters - `variants` (LiveActivityVariants) - Defines the UI for different display contexts (lockScreen, compact, minimal, expanded). - `options` (object) - Configuration options: - `activityName` (string, Optional) - For re-binding on app restart. - `deepLinkUrl` (string, Optional) - URL to open when tapped. - `channelId` (string, Optional) - Broadcast channel (iOS 18+). - `dismissalPolicy` (object, Optional) - Policy for dismissing the activity (e.g., `{ after: seconds }`). - `staleDate` (Date, Optional) - The date when the activity becomes stale. - `relevanceScore` (number, Optional) - A score indicating the relevance of the activity. ### Returns - `Promise` - A promise that resolves to the Live Activity ID. ``` -------------------------------- ### Install @use-voltra/metro Source: https://github.com/callstackincubator/voltra/blob/main/packages/metro/README.md Install the package using npm. This is typically done when you need to customize the Metro configuration directly. ```sh npm install @use-voltra/metro ``` -------------------------------- ### Install Voltra Android Client Package Source: https://github.com/callstackincubator/voltra/blob/main/packages/android-client/README.md Install the Android client package using npm. ```sh npm install @use-voltra/android-client ``` -------------------------------- ### Install @use-voltra/compiler Source: https://github.com/callstackincubator/voltra/blob/main/packages/compiler/README.md Install the compiler package directly if you need to build custom tooling on top of Voltra's source scanner. ```bash npm install @use-voltra/compiler ``` -------------------------------- ### Install Voltra CLI Source: https://github.com/callstackincubator/voltra/blob/main/website/docs/v2/getting-started/react-native-cli.mdx Install the Voltra CLI as a dev dependency. ```bash npm install --save-dev voltra ``` -------------------------------- ### Starting Live Activities Source: https://github.com/callstackincubator/voltra/blob/main/website/docs/v1/ios/development/managing-live-activities-locally.md Use `startLiveActivity()` to create and display a new Live Activity with specified UI variants and configuration options. ```APIDOC ## startLiveActivity() ### Description Creates and displays a new Live Activity. ### Parameters #### variants - **variants** (LiveActivityVariants) - Required - Defines the UI for different display contexts (lockScreen, compact, minimal, expanded). #### options - **options** (object) - Optional - Configuration options for the Live Activity. - **activityName** (string) - Optional - For re-binding on app restart. - **deepLinkUrl** (string) - Optional - URL to open when tapped. - **channelId** (string) - Optional - Broadcast channel (iOS 18+). - **dismissalPolicy** (object) - Optional - Policy for automatic dismissal. - **after** (number) - Optional - Dismiss after a specified number of seconds. - **staleDate** (number) - Optional - Timestamp for when the activity becomes stale. - **relevanceScore** (number) - Optional - Score indicating the activity's relevance. ### Returns - **Promise** - A promise that resolves to the Live Activity ID. ``` -------------------------------- ### Install Voltra iOS Client Source: https://github.com/callstackincubator/voltra/blob/main/packages/ios-client/README.md Install the iOS client package using npm. This command is essential for adding Voltra's iOS capabilities to your project. ```sh npm install @use-voltra/ios-client ``` -------------------------------- ### Install Optional Server Packages for Voltra v2 Source: https://github.com/callstackincubator/voltra/blob/main/website/docs/v2/getting-started/migration-v2.mdx Install optional server-side packages for Voltra v2 to handle iOS and Android specific server logic, as well as general server functionalities. ```bash npm install @use-voltra/ios-server @use-voltra/android-server @use-voltra/server ``` -------------------------------- ### Start Live Activity with Deep Link Source: https://github.com/callstackincubator/voltra/blob/main/website/docs/v1/ios/development/interactions.md Configure the deep link URL when starting a Live Activity. This allows your app to be launched via a deep link when the Live Activity itself is tapped. ```typescript import { useLiveActivity } from 'voltra/client' const { start } = useLiveActivity( { lockScreen: , }, { activityName: 'activity-detail', deepLinkUrl: '/voltraui/activity-detail', } ) ``` -------------------------------- ### Install Voltra Package Source: https://github.com/callstackincubator/voltra/blob/main/website/docs/v1/getting-started/installation.mdx Use this command to add Voltra to your Expo project. This is the primary step for integrating Voltra. ```bash npm install voltra # or yarn add voltra # or pnpm add voltra ``` -------------------------------- ### Button Usage Example Source: https://github.com/callstackincubator/voltra/blob/main/website/docs/v1/ios/components/interactive.md Demonstrates how to create and use a Voltra Button. Buttons fire interaction events that can be handled in your app. Requires iOS 17.0+. ```tsx Play Music ``` ```typescript import { addVoltraListener } from 'voltra/client' const subscription = addVoltraListener('interaction', (event) => { if (event.identifier === 'play-button') { // Handle play action } }) ``` -------------------------------- ### Get Active Widgets on iOS Source: https://github.com/callstackincubator/voltra/blob/main/website/docs/v2/ios/development/developing-widgets.md Fetches a list of widgets currently installed on the user's home screen. Useful for understanding which widgets are active and their configurations. ```typescript import { getActiveWidgets } from '@use-voltra/ios-client' const widgets = await getActiveWidgets() // [{ name: 'weather', family: 'systemSmall', kind: '...' }] ``` -------------------------------- ### Get Active Widgets Source: https://github.com/callstackincubator/voltra/blob/main/website/docs/v1/ios/development/developing-widgets.md Use this API to detect which widgets are currently installed on the user's home screen. Refer to 'Querying Active Widgets' for more details. ```typescript import { getActiveWidgets } from 'voltra/client' const widgets = await getActiveWidgets() // [{ name: 'weather', family: 'systemSmall', kind: '...' }] ``` -------------------------------- ### Create Notification Channel with Expo Notifications Source: https://github.com/callstackincubator/voltra/blob/main/website/docs/v1/android/development/managing-ongoing-notifications.md Use `expo-notifications` to create a notification channel, which is required before starting an ongoing notification. This example creates a channel named 'delivery_updates'. ```typescript import * as Notifications from 'expo-notifications' await Notifications.setNotificationChannelAsync('delivery_updates', { name: 'Delivery updates', importance: Notifications.AndroidImportance.DEFAULT, }) ``` -------------------------------- ### Start Live Activity with Stale Date Source: https://github.com/callstackincubator/voltra/blob/main/website/docs/v1/ios/api/configuration.md Set a staleDate to automatically dismiss the Live Activity after a specified time. This example sets the stale date to one hour from the current time. ```typescript import { startLiveActivity } from 'voltra/client' // Dismiss the Live Activity after 1 hour await startLiveActivity(variants, { staleDate: Date.now() + 60 * 60 * 1000, // 1 hour from now }) ``` -------------------------------- ### Build Plugins Source: https://github.com/callstackincubator/voltra/blob/main/CONTRIBUTING.md Execute this command to build all project plugins. ```bash npm run build:plugin ``` -------------------------------- ### Get Active Widgets - TypeScript Source: https://github.com/callstackincubator/voltra/blob/main/website/docs/v2/ios/development/querying-active-widgets.md Use this function to retrieve an array of active widget configurations. It logs the count and details of each installed widget. Note that iOS may cache widget configurations, leading to a slight delay in data. ```typescript import { getActiveWidgets } from '@use-voltra/ios-client' async function checkWidgets() { const activeWidgets = await getActiveWidgets() console.log(`User has ${activeWidgets.length} widgets installed`) activeWidgets.forEach(widget => { console.log(`- Widget Name: ${widget.name}`) console.log(` Family: ${widget.family}`) console.log(` Kind: ${widget.kind}`) }) } ``` -------------------------------- ### Start or Update Notification with upsertAndroidOngoingNotification Source: https://github.com/callstackincubator/voltra/blob/main/website/docs/v1/android/development/managing-ongoing-notifications.md Use `upsertAndroidOngoingNotification` to either start a new ongoing notification or update an existing one with a single call. This is useful for scenarios where the same flow might be re-entered, simplifying logic compared to separate start and update calls. It returns an object indicating whether the notification was 'started' or 'updated'. ```typescript import { AndroidOngoingNotification, upsertAndroidOngoingNotification, } from 'voltra/android/client' const result = await upsertAndroidOngoingNotification( , { notificationId: 'workout-1', channelId: 'fitness_updates', } ) if (result.ok) { console.log(result.action) // 'started' or 'updated' } ``` -------------------------------- ### Basic Styling with VStack and Text Source: https://github.com/callstackincubator/voltra/blob/main/website/docs/v1/ios/development/styling.md Demonstrates applying basic styles like padding, background color, border radius, font size, and color to Voltra components using the `style` prop. ```tsx import { Voltra } from 'voltra' const element = ( Styled Text ) ``` -------------------------------- ### Run Prebuild Command Source: https://github.com/callstackincubator/voltra/blob/main/website/docs/v1/android/development/custom-fonts.md After configuring the fonts, run `npx expo prebuild` to copy the font files to the correct Android asset directory. ```bash npx expo prebuild ``` -------------------------------- ### Start a Live Activity Source: https://github.com/callstackincubator/voltra/blob/main/website/docs/v1/ios/development/managing-live-activities-locally.md Initiates and displays a new Live Activity. Requires defining UI variants for different contexts and can include optional configuration like activity name, deep link, and dismissal policies. ```typescript import { startLiveActivity } from 'voltra/client' import { Voltra } from 'voltra' const variants = { lockScreen: ( Order Confirmed Your order is being prepared ), // Define compact, minimal, and expanded variants for Dynamic Island compact: Order confirmed, minimal: , expanded: ( Order Confirmed Your order is being prepared ), } const activityId = await startLiveActivity(variants, { activityName: 'order-123', // Optional: for re-binding on app restart deepLinkUrl: 'myapp://order/123', // Optional: URL to open when tapped channelId: 'CTrNsYq/Ee8AALLzHQaVlA==', // Optional: broadcast channel (iOS 18+) dismissalPolicy: { after: 30 }, staleDate: Date.now() + 60 * 60 * 1000, // 1 hour relevanceScore: 0.8, }) ``` -------------------------------- ### Create a "Hello World" Live Activity Source: https://github.com/callstackincubator/voltra/blob/main/website/docs/v1/ios/setup.mdx This component demonstrates how to start a simple Live Activity using Voltra. The JSX is automatically converted to SwiftUI for native display. ```tsx import React from 'react' import { startLiveActivity } from 'voltra/client' import { Voltra } from 'voltra' function HelloWorldActivity() { const activityUI = ( Hello World from Voltra! Your first live activity ) const startActivity = async () => { await startLiveActivity({ lockScreen: activityUI, }) } return ( Start Live Activity ) } ``` -------------------------------- ### Implement Widget Initial State Source: https://github.com/callstackincubator/voltra/blob/main/website/docs/v1/ios/development/widget-pre-rendering.md Create a file at the specified `initialStatePath` that exports a `WidgetVariants` object, defining the initial UI for different widget families. ```tsx import { Voltra, type WidgetVariants } from 'voltra' const initialState: WidgetVariants = { systemSmall: Content, systemMedium: Content, systemLarge: Content, } export default initialState ``` -------------------------------- ### Start a Live Activity Source: https://github.com/callstackincubator/voltra/blob/main/website/docs/v2/ios/development/managing-live-activities-locally.md Use `startLiveActivity` to create and display a new Live Activity with defined UI variants and configuration options. It returns the activity ID. ```typescript import { Voltra } from '@use-voltra/ios' import { startLiveActivity } from '@use-voltra/ios-client' const variants = { lockScreen: ( Order Confirmed Your order is being prepared ), // Define compact, minimal, and expanded variants for Dynamic Island compact: Order confirmed, minimal: , expanded: ( Order Confirmed Your order is being prepared ), } const activityId = await startLiveActivity(variants, { activityName: 'order-123', // Optional: for re-binding on app restart deepLinkUrl: 'myapp://order/123', // Optional: URL to open when tapped channelId: 'CTrNsYq/Ee8AALLzHQaVlA==', // Optional: broadcast channel (iOS 18+) dismissalPolicy: { after: 30 }, staleDate: Date.now() + 60 * 60 * 1000, // 1 hour relevanceScore: 0.8, }) ``` -------------------------------- ### Toggle Example Source: https://github.com/callstackincubator/voltra/blob/main/website/docs/v1/ios/components/interactive.md Example of a Voltra Toggle component, which fires an interaction event when its state changes. It supports a default value. Requires iOS 17.0+. ```tsx ``` ```typescript import { addVoltraListener } from 'voltra/client' const subscription = addVoltraListener('interaction', (event) => { if (event.identifier === 'notifications-toggle') { // Handle toggle state change } }) ``` -------------------------------- ### Handling Live Activity Interactions with Voltra Source: https://github.com/callstackincubator/voltra/blob/main/website/docs/v1/ios/development/interactions.md Use this example to set up interactive buttons and toggles in your Live Activity and listen for interaction events. Ensure you handle state updates manually after an interaction. ```typescript import { useEffect } from 'react' import { useLiveActivity } from 'voltra/client' import { Voltra } from 'voltra' import { addVoltraListener } from 'voltra/client' function MyLiveActivity() { const { start, update } = useLiveActivity( { lockScreen: ( Music Player Play Pause ), }, { activityName: 'music-player', deepLinkUrl: '/music-player', } ) useEffect(() => { const subscription = addVoltraListener('interaction', (event) => { switch (event.identifier) { case 'play-button': // Start playback console.log('Play button tapped') break case 'pause-button': // Pause playback console.log('Pause button tapped') break case 'shuffle-toggle': // Toggle shuffle mode console.log('Shuffle toggled') break } }) return () => subscription.remove() }, []) return null } ``` -------------------------------- ### Start or Update Ongoing Notification Source: https://github.com/callstackincubator/voltra/blob/main/website/docs/v1/android/development/managing-ongoing-notifications.md The `upsertAndroidOngoingNotification` function allows you to start a new ongoing notification or update an existing one with a single call. This is particularly useful for scenarios where the same flow might be re-entered, simplifying logic compared to separate start and update calls. It's also beneficial for remote updates via push notifications. ```APIDOC ## upsertAndroidOngoingNotification ### Description Starts a new ongoing notification or updates an existing one. Useful for simplifying logic when re-entering flows or for remote updates. ### Method Signature `upsertAndroidOngoingNotification(notificationContent: AndroidOngoingNotification, options: { notificationId: string, channelId: string })` ### Parameters #### Notification Content - **notificationContent** (AndroidOngoingNotification.Progress | AndroidOngoingNotification.Media | AndroidOngoingNotification.Default) - Required - The content of the ongoing notification. #### Options - **notificationId** (string) - Required - A unique identifier for the notification. - **channelId** (string) - Required - The ID of the notification channel to use. ### Request Example ```tsx import { AndroidOngoingNotification, upsertAndroidOngoingNotification, } from 'voltra/android/client' const result = await upsertAndroidOngoingNotification( , { notificationId: 'workout-1', channelId: 'fitness_updates', } ) if (result.ok) { console.log(result.action) // 'started' or 'updated' } ``` ### Response - **ok** (boolean) - Indicates if the operation was successful. - **action** (string) - Returns 'started' if a new notification was created, or 'updated' if an existing one was modified. ``` -------------------------------- ### Configure Widget Pre-rendering Source: https://github.com/callstackincubator/voltra/blob/main/website/docs/v1/android/api/plugin-configuration.md Use `initialStatePath` to specify the path to a pre-rendered widget state file. This file will be bundled and used for immediate display before dynamic updates. ```json { "widgets": [ { "id": "weather", "displayName": "Weather Widget", "targetCellWidth": 2, "targetCellHeight": 2, "initialStatePath": "./widgets/weather-initial.tsx" } ] } ``` -------------------------------- ### Configure Initial State for Server-Driven Widgets Source: https://github.com/callstackincubator/voltra/blob/main/website/docs/v1/android/development/server-driven-widgets.md Define the `initialStatePath` in the widget configuration to provide a pre-rendered default state. This content is displayed until the first server fetch completes, ensuring a meaningful initial display. ```json { "id": "dynamic_weather", "displayName": "Dynamic Weather", "description": "Weather with live server updates", "targetCellWidth": 2, "targetCellHeight": 1, "initialStatePath": "./widgets/android/weather-initial.tsx", "serverUpdate": { "url": "https://api.example.com/widgets/render", "intervalMinutes": 60 } } ``` -------------------------------- ### Swift Payload Migration Example Source: https://github.com/callstackincubator/voltra/blob/main/CONTRIBUTING.md Example of a Swift migration struct for payload schema versioning. Increment `currentVersion` and implement `VoltraPayloadMigration` to handle schema changes and ensure forward compatibility. ```swift // Example: V1ToV2Migration.swift struct V1ToV2Migration: VoltraPayloadMigration { static let fromVersion = 1 static let toVersion = 2 static func migrate(_ json: JSONValue) throws -> JSONValue { // Transform v1 payload to v2 format // Update the version field var result = json result["v"] = .int(2) return result } } // In VoltraPayloadMigrator.swift: private static let migrations: [Int: any VoltraPayloadMigration.Type] = [ 1: V1ToV2Migration.self, ] ``` -------------------------------- ### APNS Payload for Starting a Live Activity (iOS 17.2+) Source: https://github.com/callstackincubator/voltra/blob/main/website/docs/v1/ios/development/server-side-updates.md This payload is used for starting a Live Activity remotely on iOS 17.2 and later. It includes `attributes-type`, `attributes`, and an `alert` object. ```json { "aps": { "event": "start", "content-state": { "uiJsonData": "{\"lockScreen\":{\"type\":\"VStack\",\"children\":{\"type\":\"Text\",\"children\":\"Hello\",\"props\":{}}},\"props\":{}}" }, "attributes-type": "VoltraAttributes", "attributes": { "name": "some-name", "deepLinkUrl": "app://some-deep-link-url" }, "timestamp": 1764145755, "alert": { "title": "Driver arrived", "body": "Ready for pickup" } } } ``` -------------------------------- ### Implement Initial Widget State Source: https://github.com/callstackincubator/voltra/blob/main/website/docs/v2/android/development/widget-pre-rendering.md Create a file at the specified `initialStatePath` that exports a default Voltra component using `VoltraAndroid` primitives for the initial UI. ```tsx import { VoltraAndroid } from '@use-voltra/android' const InitialWeatherWidget = ( Loading weather... ) export default InitialWeatherWidget ``` -------------------------------- ### Start Android Big Text Notification Source: https://github.com/callstackincubator/voltra/blob/main/website/docs/v1/android/development/managing-ongoing-notifications.md Starts an ongoing notification with a large text content on Android. Requires a notification ID and channel ID. This is useful for displaying more detailed information. ```typescript import { AndroidOngoingNotification, startAndroidOngoingNotification, } from 'voltra/android/client' await startAndroidOngoingNotification( , { notificationId: 'match-42', channelId: 'sports_updates', } ) ``` -------------------------------- ### Configure Greeting Widget in app.json Source: https://github.com/callstackincubator/voltra/blob/main/website/docs/v2/ios/development/configurable-widgets.md This JSON configuration sets up the 'greeting_widget' as a Dynamic Widget. It specifies the entry point, display information, and defines a user-editable 'label' parameter with a default value of 'Hello'. ```json { "expo": { "plugins": [ [ "@use-voltra/ios-client", { "widgets": [ { "id": "greeting_widget", "entry": "./widgets/ios/greeting-widget.tsx", "displayName": "Greeting Widget", "description": "A Dynamic Widget with user-editable parameters", "supportedFamilies": ["systemSmall", "systemMedium"], "initialStatePath": "./widgets/ios/greeting-widget.tsx", "appIntent": { "parameters": [ { "name": "label", "title": "Label", "default": "Hello" } ] } } ] } ] ] } } ``` -------------------------------- ### Start or Update Android Ongoing Notification Source: https://github.com/callstackincubator/voltra/blob/main/website/docs/v2/android/development/managing-ongoing-notifications.md Use `upsertAndroidOngoingNotification` to either start a new ongoing notification or update an existing one with a single call. This is useful for scenarios where an app might re-enter the same flow multiple times, simplifying logic compared to separate start and update calls. It's particularly effective for remote updates via push notifications. ```typescript import { AndroidOngoingNotification } from '@use-voltra/android' import { upsertAndroidOngoingNotification, } from '@use-voltra/android-client' const result = await upsertAndroidOngoingNotification( , { notificationId: 'workout-1', channelId: 'fitness_updates', } ) if (result.ok) { console.log(result.action) // 'started' or 'updated' } ``` -------------------------------- ### Provide Initial Widget State Source: https://github.com/callstackincubator/voltra/blob/main/website/docs/v1/ios/development/server-driven-widgets.md Specify a path to a pre-rendered default state for your widget. This content is displayed before the first server fetch completes, improving user experience. ```json { "id": "dynamic_weather", "displayName": "Dynamic Weather", "description": "Weather with live server updates", "supportedFamilies": ["systemSmall", "systemMedium"], "initialStatePath": "./widgets/ios/weather-initial.tsx", "serverUpdate": { "url": "https://api.example.com/widgets/render", "intervalMinutes": 30 } } ``` -------------------------------- ### Live Activity Configuration Options Source: https://github.com/callstackincubator/voltra/blob/main/website/docs/v2/ios/development/managing-live-activities-locally.md Configure the behavior, lifecycle, and appearance of Live Activities using various options. ```APIDOC ## Configuration Options ### Description Voltra provides several configuration options to control Live Activity behavior, lifecycle, and appearance. These options can be used with `startLiveActivity()`, `updateLiveActivity()`, and `stopLiveActivity()`. ### Dismissal Policy Controls how Live Activities behave after they end. **Options:** - `'immediate'` (default): Live Activity is dismissed immediately when it ends. - `{ after: number }`: Live Activity remains visible for the specified number of seconds after ending, then automatically dismisses. **Examples:** ```typescript // Immediate dismissal (default) await startLiveActivity(variants, { dismissalPolicy: 'immediate', }) // Keep visible for 30 seconds after ending await startLiveActivity(variants, { dismissalPolicy: { after: 30 }, }) // Update dismissal timing for active Live Activities await updateLiveActivity(activityId, variants, { dismissalPolicy: { after: 300 }, // 5 minutes }) // Set dismissal timing when stopping await stopLiveActivity(activityId, { dismissalPolicy: { after: 10 }, }) ``` ### Stale Date Specifies when a Live Activity should be considered stale and automatically dismissed by iOS. **Example:** ```typescript // Dismiss after 1 hour await startLiveActivity(variants, { staleDate: Date.now() + 60 * 60 * 1000, }) // Dismiss after 2 hours await startLiveActivity(variants, { staleDate: Date.now() + 2 * 60 * 60 * 1000, }) ``` **Note:** If you provide a `staleDate` in the past, it will be ignored. ### Relevance Score Helps iOS prioritize which Live Activities to display when space is limited. **Range:** 0.0 to 1.0 (default: 0.0) **Examples:** ```typescript // High priority (e.g., active delivery) await startLiveActivity(variants, { relevanceScore: 0.8, }) // Low priority (e.g., background task) await startLiveActivity(variants, { relevanceScore: 0.2, }) ``` ### Channel ID (broadcast push, iOS 18+) Subscribes the Live Activity to a broadcast channel for server-side updates. When provided, the activity receives updates via broadcast push notifications instead of individual device tokens—one server notification updates all activities on that channel. **Example:** ```typescript // For shared content (e.g., live sports, flight status) await startLiveActivity(variants, { activityName: 'match-123', channelId: 'CTrNsYq/Ee8AALLzHQaVlA==', // From APNs channel management }) ``` **Requirements:** Requires `enablePushNotifications: true` in the Voltra plugin and the Broadcast Capability enabled in your Apple Developer account. See [Server-side updates](./server-side-updates.md#broadcast-push-notifications-ios-18) for details. ``` -------------------------------- ### Configure Widget Initial State Path Source: https://github.com/callstackincubator/voltra/blob/main/website/docs/v2/ios/development/widget-pre-rendering.md Add `initialStatePath` to your widget configuration in `app.json` to specify the file for pre-rendering the widget's initial state. ```json { "expo": { "plugins": [ [ "@use-voltra/ios-client", { "widgets": [ { "id": "weather", "displayName": "Weather Widget", "description": "Shows current weather conditions", "supportedFamilies": ["systemSmall", "systemMedium", "systemLarge"], "initialStatePath": "./widgets/weather-initial.tsx" } ] } ] ] } } ``` -------------------------------- ### Start Live Activity with Channel ID (TypeScript) Source: https://github.com/callstackincubator/voltra/blob/main/website/docs/v1/ios/development/server-side-updates.md Use this function to start a Live Activity and subscribe it to a broadcast channel. This is for iOS 18+; older versions will fall back to token-based updates. ```typescript import { startLiveActivity } from 'voltra/client' import { Voltra } from 'voltra' const activityId = await startLiveActivity(variants, { activityName: 'match-123', channelId: 'CTrNsYq/Ee8AALLzHQaVlA==', // Channel ID from your server }) ``` -------------------------------- ### Voltra Android Client Quick Example Source: https://github.com/callstackincubator/voltra/blob/main/packages/android-client/README.md A React Native component and function to display weather information in a Voltra Android widget and update it. This example uses Voltra's Box, Column, and Text components for layout and styling. ```tsx import { updateAndroidWidget, VoltraAndroid } from '@use-voltra/android-client' const WeatherWidget = ({ temperature, condition }: { temperature: number; condition: string }) => ( {temperature}°C {condition} ) export async function refreshWeatherWidget() { await updateAndroidWidget('my_widget', ) } ``` -------------------------------- ### Configure Widget Initial State Path Source: https://github.com/callstackincubator/voltra/blob/main/website/docs/v1/ios/development/widget-pre-rendering.md Add `initialStatePath` to your widget configuration in `app.json` to specify the location of the initial state file. ```json { "expo": { "plugins": [ [ "voltra", { "widgets": [ { "id": "weather", "displayName": "Weather Widget", "description": "Shows current weather conditions", "supportedFamilies": ["systemSmall", "systemMedium", "systemLarge"], "initialStatePath": "./widgets/weather-initial.tsx" } ] } ] ] } } ``` -------------------------------- ### AreaMark Example Source: https://github.com/callstackincubator/voltra/blob/main/website/docs/v1/android/charts.md Use AreaMark to quickly visualize overall volume or rise/fall patterns. Supports interpolation. ```tsx ``` -------------------------------- ### Live Activity with Interactive Elements Source: https://github.com/callstackincubator/voltra/blob/main/website/docs/v2/ios/development/interactions.md Use this example to create a Live Activity with buttons and toggles. Ensure you handle interaction events asynchronously using `addVoltraListener`. Requires iOS 17.0+ for interactivity. ```typescript import { useEffect } from 'react' import { Voltra } from '@use-voltra/ios' import { useLiveActivity } from '@use-voltra/ios-client' import { addVoltraListener } from '@use-voltra/ios-client' function MyLiveActivity() { const { start, update } = useLiveActivity( { lockScreen: ( Music Player Play Pause ), }, { activityName: 'music-player', deepLinkUrl: '/music-player', } ) useEffect(() => { const subscription = addVoltraListener('interaction', (event) => { switch (event.identifier) { case 'play-button': // Start playback console.log('Play button tapped') break case 'pause-button': // Pause playback console.log('Pause button tapped') break case 'shuffle-toggle': // Toggle shuffle mode console.log('Shuffle toggled') break } }) return () => subscription.remove() }, []) return null } ``` -------------------------------- ### Create a 'Hello World' Live Activity with Voltra Source: https://github.com/callstackincubator/voltra/blob/main/website/docs/v2/ios/setup.mdx This component demonstrates how to create a simple Live Activity using Voltra's JSX components. The `startLiveActivity` function is used to display the UI on the lock screen. ```tsx import React from 'react' import { Voltra } from '@use-voltra/ios' import { startLiveActivity } from '@use-voltra/ios-client' function HelloWorldActivity() { const activityUI = ( Hello World from Voltra! Your first live activity ) const startActivity = async () => { await startLiveActivity({ lockScreen: activityUI, }) } return ( Start Live Activity ) } ``` -------------------------------- ### AreaMark Example Source: https://github.com/callstackincubator/voltra/blob/main/website/docs/v1/ios/charts.md Use AreaMark to visualize overall volume or rise/fall patterns. Supports custom color and interpolation. ```tsx ```