Interactive Widget and LiveActivity

The Scripting app supports adding interactivity to widgets and LiveActivity, allowing you to create dynamic and interactive UIs using Button and Toggle components. These controls can execute AppIntents to trigger actions, making your widgets and live activities more powerful.


1. Introduction to AppIntents

What are AppIntents?

An AppIntent defines a specific action that can be triggered by a control (e.g., a Button or Toggle) in a widget or LiveActivity UI. AppIntents enable seamless interaction and functionality by linking UI components with executable logic.

Supported Protocols

AppIntents can implement the following protocols:

  • AppIntent: General-purpose intents for triggering custom actions.
  • AudioPlaybackIntent: Handles audio playback (e.g., play, pause, or toggle audio states).
  • AudioRecordingIntent: Manages audio recording states (requires iOS 18+ and a LiveActivity to stay active during recording).
  • LiveActivityIntent: Modifies or manages LiveActivity states.

2. Registering an AppIntent

To use an AppIntent, it must first be registered in the app_intents.tsx file using the AppIntentManager.register method.

Example: Registering AppIntents

1// app_intents.tsx
2
3import { AppIntentManager, AppIntentProtocol } from "scripting"
4
5// Register an AppIntent
6const IntentWithoutParams = AppIntentManager.register({
7  name: "IntentWithoutParams",
8  protocol: AppIntentProtocol.AppIntent,
9  perform: async (params: undefined) => {
10    // Perform a custom action
11    console.log("Intent triggered")
12    // Optionally reload widgets
13    Widget.reloadAll()
14  }
15})
16
17// Register an AppIntent with parameters
18const ToggleIntentWithParams = AppIntentManager.register({
19  name: "ToggleIntentWithParams",
20  protocol: AppIntentProtocol.AudioPlaybackIntent,
21  perform: async (audioName: string) => {
22    // Perform action based on the parameter
23    console.log(`Toggling audio playback for: ${audioName}`)
24    Widget.reloadAll()
25  }
26})

3. Using AppIntents in Widgets or LiveActivity UIs

After registering an AppIntent, it can be linked to interactive components like Button and Toggle in your widget.tsx or LiveActivity UI file.

Example: Using AppIntents in a Widget

1// widget.tsx
2
3import { VStack, Button, Toggle } from "scripting"
4import { IntentWithoutParams, ToggleIntentWithParams } from "./app_intents"
5
6function WidgetView() {
7  const [checked, setChecked] = useState(false)
8
9  return (
10    <VStack>
11      <Button
12        title="Tap me"
13        intent={IntentWithoutParams(undefined)} // Trigger the intent without parameters
14      />
15      <Toggle
16        title="Play or Pause"
17        value={checked}
18        intent={ToggleIntentWithParams("audio_name")} // Trigger the intent with a parameter
19      />
20    </VStack>
21  )
22}
23
24// Present the widget
25Widget.present(<WidgetView />)

4. API Reference

AppIntentManager.register

Registers an AppIntent for use in widgets or LiveActivity UIs.

Parameters:

  • name (string): A unique name for the intent.
  • protocol (AppIntentProtocol): Specifies the type of intent (e.g., AppIntent, AudioPlaybackIntent).
  • perform (function): The function to execute when the intent is triggered.

Returns:

  • An AppIntentFactory function that can be used to create instances of the registered intent.

Button Component

A tappable button that triggers an AppIntent.

Props:

  • title (string): The button’s label.
  • intent (AppIntent<any>): The AppIntent to execute when the button is tapped.
  • systemImage (optional): An SF Symbol to display on the button.

Toggle Component

A toggle switch that triggers an AppIntent when its value changes.

Props:

  • value (boolean): Indicates the toggle's state (on/off).
  • intent (AppIntent<any>): The AppIntent to execute when the toggle is toggled.
  • title (string): The toggle’s label.
  • systemImage (optional): An SF Symbol to display with the toggle.

5. Notes and Best Practices

  • Use Widget.reloadAll() within perform functions to update widgets dynamically after executing an intent.
  • Define your AppIntents in app_intents.tsx for organization and reusability.
  • Use appropriate protocols (e.g., AudioPlaybackIntent) to match the intent's functionality.

Enjoy building interactive widgets and LiveActivities with Scripting! Let your creativity shine by leveraging the power of AppIntents for dynamic, interactive UIs.