← 所有文章

iOS 26 的小工具介面:一個 App Intent,多處呈現

多年來,小工具一直只是一張快照。系統依時間軸繪製您的視圖,使用者看一眼,任何點按都只是開啟 App。這套模型已成過去。自 iOS 17 起,小工具便能搭載按鈕與切換開關,無須啟動任何東西就能執行程式碼,而它們所執行的程式碼就是 App Intent1。控制中心的控制項是如此,即時動態裡的按鈕也是如此。一旦看清這點,iOS 26 的小工具介面就不再像是三個各自獨立的API,而是合而為一:系統用來呈現您 App Intents 的多個場所,各有不同的版面空間,底層管路卻完全相同。

這個重新框定,正是本文的核心。學會一次 App Intent,就能點亮主畫面、鎖定畫面、控制中心、動作按鈕、動態島,以及(還是同一個 intent)Siri 與 Apple Intelligence。若寫成三個彼此脫節的功能,您付出四倍的工夫,換來的結果反而更差。

重點摘要

  • 互動式小工具(iOS 17+): 在小工具視圖中放入 Button(intent:)Toggle(isOn:intent:);系統會在您的小工具擴充功能中、於 App 之外執行該 App Intent 的 perform(),接著重新載入時間軸1
  • 控制中心控制項(iOS 18+):ControlWidgetButtonControlWidgetToggle 建構而成的 ControlWidget,背後同樣由 App Intents 支撐,會出現在控制中心、鎖定畫面與動作按鈕上2
  • 即時動態(ActivityKit): ActivityAttributes 搭配 ActivityConfiguration 驅動鎖定畫面與動態島;由伺服器驅動的更新透過推播送達,裡頭的按鈕同樣是 App Intents3
  • iOS 26 改的是呈現方式,不是模型: 小工具獲得 Liquid Glass 的呈現外觀與強調色繪製模式,但「App Intents 作為呈現面」的架構自 iOS 18 以來並未改變4
  • 一以貫之的事實是:一個小工具按鈕、一個控制項、一句 Siri 語句、一個 Apple Intelligence 操作,全都可以是同一個 App Intent。能力只需設計一次。

互動式小工具:不開啟 App 的那顆按鈕

機制很小,值得精確說明。您在小工具的視圖裡加入一個 SwiftUI ButtonToggle,但傳入的不是動作閉包,而是一個 App Intent1

struct WaterWidgetView: View {
    let logged: Int

    var body: some View {
        VStack {
            Text("\(logged) glasses")
            Button(intent: LogWaterIntent()) {
                Label("Add", systemImage: "plus")
            }
        }
    }
}

當使用者點按時,系統會在您的小工具擴充功能內執行 LogWaterIntent.perform()。App 不會啟動。intent 完成它的工作(寫入共享儲存、更新計數),小工具的時間軸隨即重新載入以顯示結果。

Toggle 透過 SetValueIntent 以相同方式運作,後者會接收到使用者剛剛設定的新開/關值:

struct ToggleReminderIntent: SetValueIntent {
    static let title: LocalizedStringResource = "Toggle Reminder"

    @Parameter(title: "Enabled")
    var value: Bool

    func perform() async throws -> some IntentResult {
        ReminderStore.shared.enabled = value
        return .result()
    }
}

小工具綁定 Toggle(isOn: store.enabled, intent: ToggleReminderIntent()),系統將 value 設為新狀態、執行 perform(),然後重新載入。形狀與按鈕相同,只多了一個參數1

有兩項限制界定了您在這裡能做的事,而兩者都很容易違反。第一,perform() 在受限的小工具擴充功能環境中執行,執行預算相當緊縮;它適合快速的狀態變更,而非網路上傳或繁重運算。第二,小工具反映狀態,而非任意動畫 UI。您改變資料,時間軸便重新繪製;您無法執行自訂的轉場。把互動設計成「翻動一個值、顯示新值」,它就能運作。一旦想要更多,系統就會與您對抗。

控制中心控制項:同一個 intent,換一個房間

iOS 18 向第三方控制項開放了控制中心、鎖定畫面與動作按鈕,而其API刻意與小工具平行對應2。控制項是一個 ControlWidget,其主體是接上 App Intent 的 ControlWidgetButtonControlWidgetToggle

struct LogWaterControl: ControlWidget {
    var body: some ControlWidgetConfiguration {
        StaticControlConfiguration(kind: "com.example.logWater") {
            ControlWidgetButton(action: LogWaterIntent()) {
                Label("Log Water", systemImage: "drop.fill")
            }
        }
    }
}

如果 LogWaterIntent 已經在驅動您的互動式小工具,那麼這個控制項幾乎是免費的:同一個 intent,換個外殼而已。這正是架構帶來的回報。控制項並非該功能的第二套實作;它是您早已寫好那套功能的第二個掛載點。切換型控制項使用 SetValueIntent,做法與小工具的切換開關完全相同,因此只需建構一次的「靜音」「開始工作階段」或「切換深色模式」能力,無須新增邏輯,便會出現在控制中心、鎖定畫面與動作按鈕上2

即時動態:會自我更新的呈現面

即時動態是第三個場所,也是活動零件最多的一個。ActivityAttributes 型別定義靜態與動態內容,ActivityConfiguration 繪製鎖定畫面的呈現外觀與動態島的各區域,而 ActivityKit 負責開始、更新與結束該活動3。即時動態裡的按鈕,同樣是 App Intents,所以動態島中的「暫停」或「下一個」控制項,執行的就是與小工具按鈕同類的 intent。

讓即時動態自成一門學問的部分,是它的更新路徑。您在本機更新的計時器很單純。但由伺服器端事件(一筆外送正在移動、一場比賽的比分變動)驅動的活動,是透過推播更新:您註冊 pushTokenUpdates、從後端送出 ActivityKit 推播酬載,系統便在您的 App 完全沒有執行的情況下更新鎖定畫面與動態島3。這既相當強大,也相當容易出錯,因為此時您活動的正確性,取決於一份伺服器契約、推播的可靠度,以及一套過期日期策略,而不只是本機程式碼。

iOS 26 究竟改了什麼

iOS 26 小工具的頭條是呈現,而非架構。小工具採用 Liquid Glass 材質並獲得強調色繪製模式,因此能與系統全新的設計語言一致,並在作業系統重新著色內容的情境中正確染色4。這影響小工具在主畫面、鎖定畫面與待機顯示中的外觀,值得做一次設計檢視。但它並未改變互動的運作方式。如果您在 iOS 18 上已建構好互動式小工具與控制項,那麼 iOS 26 的動作是一次視覺翻新,而非重寫。對於「iOS 26『引入』了互動式小工具」這類說法,應抱持懷疑;互動性在 iOS 17 就已推出,控制項在 iOS 18,而 iOS 26 只是讓它們看起來與系統其餘部分一致。

不過 Liquid Glass 帶來的設計影響是實實在在的。小工具是系統合成於桌布之上、並透過玻璃外觀層折射的內容,因此規範 App 內 Liquid Glass 的同一套規則同樣適用:尊重功能層與內容層的分層,別用玻璃讀不出來的厚重自訂背景去與材質對抗。

把架構說清楚

這就是值得牢記的模型。App Intent 是一個有名稱、有型別、有描述的能力。iOS 給您一組不斷增加的場所,供您掛載這項能力:

  • 小工具裡的 ButtonToggle
  • 控制中心鎖定畫面動作按鈕上的 ControlWidget
  • 即時動態及其動態島裡的按鈕。
  • 一句 Siri 語句與一個捷徑動作。
  • 一個 Apple Intelligence 能代使用者調用的操作5

上述每一個,都是同一個帶有 perform() 方法的 AppIntent 型別。功夫全在於把那項能力設計好:清楚的名稱、有型別的參數、快速且具冪等性的 perform(),以及一個合理的結果。做好這一次,各個呈現面便都只是外殼。這與我先前談 App Intents 是 通往您 App 的真正API,以及 iOS App 如今所暴露的 三個呈現面 的論點如出一轍:小工具介面不是您要打造的功能,而是您的各項能力一旦存在,便會現身的場所。

何時不必費這個工

小工具介面會獎賞那些具備真正可一瞥即知的狀態與快速操作的 App:追蹤器、計時器、切換開關、正在播放的控制項。它不會獎賞一切。

  • 沒有可一瞥即知的狀態,就別做小工具。 如果您的 App 沒有任何值得不開啟就展示的東西,那麼小工具就是一件裝飾,代價是維護成本與一個額外的擴充功能目標。
  • 繁重或緩慢的操作,不屬於這裡的 perform() 小工具與控制項的執行環境是受限的。如果操作需要實際的時間或實際的運算,按鈕就該開啟 App 並進入一個準備好的狀態,而不是在擴充功能裡假裝完成工作。
  • 替不是「即時」的事物做即時動態。 即時動態是為有時限、正在主動變化的事件而設。把它當成常駐的狀態徽章,是對這個呈現面的誤讀,也是讓自己快速登上系統活動預算黑名單的捷徑。

真正的本領,不在於學會三個API,而在於設計出值得掛載的 App Intents,再把它們掛載到使用者本來就在的地方:他們會去看的主畫面、會滑去的控制中心、早已向他們顯示著某些東西的動態島。把能力用心地建構一次,iOS 便會免費把各個呈現面交到您手上。

常見問答

iOS 26 引入了互動式小工具嗎?

沒有。互動式小工具在 iOS 17 推出,控制中心控制項在 iOS 18;iOS 26 讓它們採用 Liquid Glass 材質與強調色繪製,以便與系統設計語言一致4。對於「iOS 26『引入』了互動式小工具」這類說法應抱持懷疑:iOS 26 的變化是視覺翻新,而非重寫。

iOS 小工具裡的按鈕究竟如何完成工作?

按鈕執行一個 App Intent。小工具裡的 ButtonToggle 會調用一個有名稱、有型別、帶 perform() 方法的 AppIntent,因此小工具無須開啟 App 即可動作。同一個 intent 還驅動著控制中心控制項、即時動態按鈕、Siri 語句與捷徑動作5

iOS 26 對小工具究竟改了什麼?

改的是呈現,不是架構。小工具採用 Liquid Glass 並獲得強調色繪製模式,以便在主畫面、鎖定畫面與待機顯示中正確染色4。互動的運作方式與 iOS 18 上完全相同,因此既有的互動式小工具需要的是一次設計檢視,而非重寫。

App 沒有執行時,即時動態如何更新?

透過推播。您註冊 pushTokenUpdates、從後端送出 ActivityKit 推播酬載,系統便在您的 App 沒有執行的情況下更新鎖定畫面與動態島3。這使得活動的正確性取決於一份伺服器契約、推播的可靠度,以及一套過期日期策略,而不只是本機程式碼。

單一個 App Intent 能出現在哪些地方?

同一個 AppIntent 型別可掛載於小工具的 ButtonToggle、控制中心/鎖定畫面/動作按鈕上的 ControlWidget、即時動態及其動態島、一句 Siri 語句、一個捷徑動作,以及作為 Apple Intelligence 可調用的操作5。能力設計一次,各個呈現面便都只是外殼。

我什麼時候不該做小工具或即時動態?

當 App 沒有任何值得不開啟就展示、可一瞥即知的狀態時,就略過小工具。在受限的小工具環境裡,別把繁重或緩慢的操作放進 perform();改為開啟 App 並進入一個準備好的狀態。另外,別把即時動態當成常駐的狀態徽章;它們是為有時限、正在主動變化的事件而設,誤用一個就會燒掉您的活動預算。



  1. Apple Developer,“Adding interactivity to widgets and Live Activities”。互動式小工具(iOS 17+)使用由 AppIntent(切換開關則用 SetValueIntent)支撐的 SwiftUI Button(intent:)Toggle(isOn:intent:);intent 的 perform() 在小工具擴充功能中執行,無須啟動 App,時間軸隨即重新載入以反映結果。 

  2. Apple Developer,“Creating controls to perform actions across the system” 以及 ControlWidget 協定。控制項(iOS 18+)由接上 App Intents 的 ControlWidgetButtonControlWidgetToggle 建構,並出現在控制中心、鎖定畫面與動作按鈕上。 

  3. Apple Developer,“ActivityKit” 以及 “Displaying live data with Live Activities”ActivityAttributesActivityConfiguration 定義並繪製鎖定畫面與動態島;ActivityKit 負責開始、更新與結束活動,而由伺服器驅動的更新使用推播搭配 pushTokenUpdates。 

  4. iOS 26 小工具繪製:小工具採用 Liquid Glass 材質與強調色繪製模式,透過 WidgetRenderingMode\.widgetRenderingMode 環境值控制。互動模型(小工具與控制項中的 App Intents)自 iOS 17(小工具)與 iOS 18(控制項)以來並未改變。Apple,“WWDC 2025: the new software design” 以及 WidgetKit 文件。 

  5. Apple Developer,“App Intents”。同一個 AppIntent 型別,是系統透過 Siri、捷徑、Spotlight、小工具與控制項呈現面,以及 Apple Intelligence 所暴露的基本單位。作者對跨呈現面模型的分析:App Intents 是 Apple 通往您 App 的全新APIApp Intents 2 與 iOS 26 的新增功能,以及 iOS App 的三個呈現面。 

相關文章

Live Activities 是狀態機,不是徽章

Return 的 Live Activity 看起來像鎖定畫面上的倒數計時。它其實是一台具備五種生命週期狀態與三條解除路徑的機器。生產環境的程式碼與錯誤實錄。

6 分鐘閱讀

Apple 的 Translation 框架:免費、裝置端執行,而且比表面更銳利

Apple 的 Translation 框架:透過 translationPresentation 與 TranslationSession 提供免費的裝置端翻譯,以及示範影片略過的離線下載眉角。

2 分鐘閱讀

The Robots Are Taking Exams in My Search Console

First-party GSC data: 91% of 3.8M impressions fail a human-query filter. Exam questions, pasted errors, and agent sweeps…

10 分鐘閱讀