Skip to content

Commit 42373bb

Browse files
committed
feat: support multiple versions
1 parent 11e9e89 commit 42373bb

File tree

2,868 files changed

+318579
-151405
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

2,868 files changed

+318579
-151405
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ doc_build/
1414
.idea
1515

1616
Scripting Documentation
17+
Scripting Documentation-tf
1718
Scripting Documentation.zip
1819

1920
doc_build.zip

bun.lock

Lines changed: 20 additions & 30 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

docs/TestFlight/en/_nav.json

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
[
2+
{
3+
"text": "docs",
4+
"link": "/guide/Quick%20Start",
5+
"activeMatch": "/guide/"
6+
},
7+
{
8+
"text": "privacy",
9+
"link": "/privacy/policy",
10+
"activeMatch": "/privacy/"
11+
}
12+
]
Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
---
2+
title: AppIntent
3+
description: This interface serves as the core mechanism for executing script logic behind controls in Widgets, Live Activities, and ControlWidgets.
4+
5+
---
6+
7+
`AppIntentManager` is used to **register and manage AppIntents** in the **Scripting** app. It serves as the core mechanism for executing script logic behind controls in **Widgets**, **Live Activities**, and **ControlWidgets**.
8+
9+
All `AppIntent`s **must** be defined in the `app_intents.tsx` file. When an intent is executed, the script runs in the `"app_intents"` environment (`Script.env === "app_intents"`).
10+
11+
Once registered, these intents can be triggered by **Button** and **Toggle** controls within Widgets, Live Activities, or ControlWidgets, allowing users to define interactive behavior via script.
12+
13+
---
14+
15+
## 1. Type Definitions
16+
17+
### `AppIntent<T>`
18+
19+
Represents a concrete intent instance with parameters and metadata.
20+
21+
| Property | Type | Description |
22+
| ---------- | ------------------- | -------------------------------------------------------------------------- |
23+
| `script` | `string` | The internal script path. Automatically generated by the system. |
24+
| `name` | `string` | The name of the AppIntent. Must be unique. |
25+
| `protocol` | `AppIntentProtocol` | The protocol the intent conforms to (e.g., general, audio, Live Activity). |
26+
| `params` | `T` | The parameters to be passed when the intent is executed. |
27+
28+
---
29+
30+
### `AppIntentFactory<T>`
31+
32+
A **factory function** that creates an `AppIntent` instance with specified parameters.
33+
34+
```ts
35+
type AppIntentFactory<T> = (params: T) => AppIntent<T>
36+
```
37+
38+
---
39+
40+
### `AppIntentPerform<T>`
41+
42+
A function that handles intent execution logic asynchronously.
43+
44+
```ts
45+
type AppIntentPerform<T> = (params: T) => Promise<void>
46+
```
47+
48+
---
49+
50+
### `AppIntentProtocol`
51+
52+
An enumeration that defines the behavior type of the intent.
53+
54+
| Enum Value | Description |
55+
| -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
56+
| `AppIntent` (0) | A general-purpose AppIntent for typical operations. |
57+
| `AudioPlaybackIntent` (1) | An intent that plays, pauses, or otherwise modifies audio playback. |
58+
| `AudioRecordingIntent` (2) | *(iOS 18.0+)* An intent that starts, stops, or modifies audio recording. **Note**: On iOS/iPadOS, when using the `AudioRecordingIntent` protocol, you must start a **Live Activity** at the beginning of the recording and keep it active for the entire session. If you don't, the recording will be automatically stopped. |
59+
| `LiveActivityIntent` (3) | An intent that starts, pauses, or modifies a Live Activity. |
60+
61+
---
62+
63+
## 2. `AppIntentManager` Class
64+
65+
### `AppIntentManager.register<T>(options): AppIntentFactory<T>`
66+
67+
Registers a new `AppIntent` by specifying its name, protocol, and perform logic. When a control (e.g., Button or Toggle) triggers the intent, the associated `perform` function is called.
68+
69+
```ts
70+
static register<T = undefined>(options: {
71+
name: string;
72+
protocol: AppIntentProtocol;
73+
perform: AppIntentPerform<T>;
74+
}): AppIntentFactory<T>
75+
```
76+
77+
#### Parameters:
78+
79+
| Property | Type | Description |
80+
| ---------- | --------------------- | ------------------------------------------------------------------------------------------------------------------ |
81+
| `name` | `string` | A unique identifier for the AppIntent. |
82+
| `protocol` | `AppIntentProtocol` | The protocol this intent implements. |
83+
| `perform` | `AppIntentPerform<T>` | The asynchronous function executed when the intent is triggered. The `params` argument is passed from the control. |
84+
85+
#### Returns:
86+
87+
* **`AppIntentFactory<T>`**: A factory function that creates an `AppIntent` instance with the specified parameters.
88+
89+
#### Example:
90+
91+
```tsx
92+
// app_intents.tsx
93+
export const ToggleDoorIntent = AppIntentManager.register({
94+
name: "ToggleDoorIntent",
95+
protocol: AppIntentProtocol.AppIntent,
96+
perform: async ({ id, newState }: { id: string; newState: boolean }) => {
97+
// Custom logic: toggle the door state
98+
await setDoorState(id, newState)
99+
// Notify UI to refresh toggle state
100+
ControlWidget.reloadToggles()
101+
}
102+
})
103+
```
104+
105+
In a control view file (e.g., `control_widget_toggle.tsx`):
106+
107+
```tsx
108+
ControlWidget.present(
109+
<ControlWidgetToggle
110+
intent={ToggleDoorIntent({ id: "door1", newState: !currentState })}
111+
label={{
112+
title: "Door 1",
113+
systemImage: currentState ? "door.garage.opened" : "door.garage.closed"
114+
}}
115+
activeValueLabel={{ title: "The door is opened" }}
116+
inactiveValueLabel={{ title: "The door is closed" }}
117+
/>
118+
)
119+
```
120+
121+
In a widget file (`widget.tsx`):
122+
123+
```tsx
124+
<Toggle
125+
title="Door 1"
126+
value={currentState}
127+
intent={ToggleDoorIntent({ id: "door1", newState: !currentState })}
128+
/>
129+
```
130+
131+
---
132+
133+
## 3. Execution Environment
134+
135+
All AppIntents registered via `AppIntentManager` are executed in the `"app_intents"` environment.
136+
This allows safe use of APIs suitable for background execution, such as:
137+
138+
* Fetching data from the network
139+
* Controlling Live Activities
140+
* Triggering control view refreshes
141+
142+
---
143+
144+
## 4. Best Practices
145+
146+
1. **Centralized Definitions**: All AppIntents **must** be defined in `app_intents.tsx` for discoverability and maintainability.
147+
2. **Strong Typing**: Define explicit parameter types `T` for both `perform` and control usage to benefit from type checking and autocomplete.
148+
3. **Choose the Right Protocol**:
149+
150+
* General operation → `AppIntent`
151+
* Audio playback → `AudioPlaybackIntent`
152+
* Audio recording → `AudioRecordingIntent` *(requires iOS 18+, with Live Activity)*
153+
* Live Activity control → `LiveActivityIntent`
154+
4. **Trigger UI Updates**: If the intent modifies a UI state (e.g., toggle), call:
155+
156+
* `ControlWidget.reloadButtons()`
157+
* `ControlWidget.reloadToggles()`
158+
* `Widget.reloadAll()`
159+
depending on where the control is hosted.

0 commit comments

Comments
 (0)