iOS 26中的App Intents 2.0:視覺智慧、互動式片段與延遲屬性
App Intents於iOS 16推出,是Apple為Shortcuts、Siri與Spotlight打造的結構化動作API;iOS 17將其擴展至由App Intents驅動的Widget;iOS 18則使其成為Apple Intelligence動作介面的契約。iOS 26更進一步將App Intents延伸至視覺智慧(Visual Intelligence,來自第三方App的圖像搜尋結果)、互動式片段(可組合進系統情境的小型彈出式UI視窗)、實體檢視註解(實體在內嵌時的呈現方式)以及@DeferredProperty(非同步運算的實體屬性)1。這些擴展並未改變App Intents的核心模型,而是新增了App可採用的參與介面。
本文將對照Apple文件逐一說明iOS 26的新增內容。切入角度是「現有採用App Intents的App,透過加入iOS 26一致性能獲得哪些新介面」,因為大多數已採用App Intents的App都已具備基礎類型,而iOS 26的工作重點在於將這些類型延伸至新的情境中。
TL;DR
IntentValueQuery是用於整合視覺智慧的新通訊協定。此查詢接受SemanticContentDescriptor(使用者的視覺情境),並回傳App認為相關的AppEntity實例陣列2。@DeferredProperty宣告一個值以非同步方式運算的實體屬性。當系統真正需要時才會載入該屬性,避免為擁有許多廉價顯示欄位與少數昂貴運算欄位的實體付出前置成本。- 互動式App Intents片段(Snippets)讓App能在Spotlight、視覺智慧或Siri回應介面等系統情境中呈現一個小型彈出視窗(包含按鈕、文字、控制項)。片段是綁定到App Intent結果的SwiftUI檢視。
- 實體檢視註解讓App能宣告
AppEntity應如何在不同系統情境下呈現(Spotlight中的精簡列、視覺智慧中的主視覺卡片、類似Live Activity風格的Widget)。 - 系列中的App Intents文章涵蓋了基礎模型;本文則將其延伸至iOS 26的新參與介面。系列中的App Intents與MCP工具對比則探討Apple Intelligence意圖介面與通用代理MCP工具之間的路由問題。
視覺智慧:IntentValueQuery與SemanticContentDescriptor
iOS 26在App Intents上的旗艦級新增功能是視覺智慧整合2。流程如下:
- 使用者拍照、擷取螢幕截圖或將相機對準某個物體。
- 系統的視覺智慧層提取視覺與語意情境(影像中有什麼、使用者可能想了解什麼)。
- 系統以該語意情境查詢每個註冊了
IntentValueQuery的App。 - 每個App回傳相關的
AppEntity實例;系統彙整後在視覺智慧UI中呈現。 - 使用者點選某個實體,便會進入原始App的對應情境。
開發者介面是一個遵循IntentValueQuery的結構,包含一個接受SemanticContentDescriptor的values(for:)方法:
import AppIntents
struct ProductLookupQuery: IntentValueQuery {
func values(for descriptor: SemanticContentDescriptor) async throws -> [Product] {
// descriptor.labels: detected category and content labels
// descriptor.pixelBuffer: the visual content as a CVReadOnlyPixelBuffer
// (use VideoToolbox/CoreImage to convert if needed)
let candidates = try await catalog.search(labels: descriptor.labels)
return candidates.map(Product.init)
}
}
SemanticContentDescriptor攜帶兩個由系統填入的欄位:labels(偵測到的類別與內容標籤陣列,例如「葡萄酒瓶」、「黑皮諾」、「標籤文字」等)以及pixelBuffer(基礎影像資料,型別為CVReadOnlyPixelBuffer,供想要對內容執行自家視覺模型的App使用)。App的工作是將這些訊號對應到自身資料,並回傳匹配的實體。
正確的採用模式:購物App針對其產品目錄實作此查詢(視覺情境→匹配產品),葡萄酒App針對其酒瓶資料庫(標籤影像→葡萄酒條目),食譜App針對其食譜資料庫(食材照片→匹配食譜)。
@DeferredProperty:非同步實體值
現有的AppEntity類型以靜態方式宣告其屬性。每個屬性都必須在實體回傳前完成運算。對於屬性成本不一的實體(快速的標題/副標題/影像,緩慢的伺服器詳細描述),這種全有全無的運算方式相當浪費。
@DeferredProperty(iOS 26+)將屬性宣告為非同步運算3:
import AppIntents
struct Recipe: AppEntity {
static var typeDisplayRepresentation = TypeDisplayRepresentation(...)
static var defaultQuery = RecipeQuery()
@Property(title: "Title")
var title: String
@Property(title: "Cuisine")
var cuisine: String
@DeferredProperty(title: "Detailed Instructions")
var instructions: String {
get async throws {
try await loadInstructionsFromBackend(id: id)
}
}
}
延遲屬性的getter為非同步;只有在系統真正需要該值時才會執行(例如實體被選取進行詳細顯示時)。對於從查詢回傳、僅用於選取UI的實體,延遲屬性永遠不會被運算。
此模式適用於任何具備建構快速欄位(id、title、summary)加上建構昂貴欄位(完整內文、運算指標、伺服器擷取資料)的實體。若沒有@DeferredProperty,開發者只能選擇全部運算(浪費)或僅運算便宜欄位再加上一個獨立的「載入詳情」意圖(更複雜)。
互動式片段與SnippetIntent
iOS 26引入了專屬的SnippetIntent通訊協定來處理片段形式的互動,與先前版本既有的ShowsSnippetView一致性AppIntent模式並存4。SnippetIntent新增了一個靜態的reload()方法,系統可呼叫此方法來重新整理片段內容,而無須重新呼叫整個意圖:
struct WeatherSnippet: SnippetIntent {
static var title: LocalizedStringResource = "Weather Snippet"
@Parameter(title: "City")
var city: City
func perform() async throws -> some IntentResult & ShowsSnippetView {
let forecast = try await weatherService.forecast(for: city)
return .result(view: ForecastSnippet(forecast: forecast))
}
static func reload() async throws {
// Triggered by the system when it wants fresh snippet data
// (e.g., after the data source signals an update)
}
}
對於非片段專用、但希望在回應上附加片段檢視的意圖,既有的AppIntent+ShowsSnippetView模式仍可運作:
struct WeatherForecastIntent: AppIntent {
static var title: LocalizedStringResource = "Weather Forecast"
@Parameter(title: "City")
var city: City
func perform() async throws -> some IntentResult & ProvidesDialog & ShowsSnippetView {
let forecast = try await weatherService.forecast(for: city)
return .result(
dialog: "Here's the forecast for \(city.name).",
view: ForecastSnippet(forecast: forecast)
)
}
}
struct ForecastSnippet: View {
let forecast: Forecast
var body: some View {
VStack(alignment: .leading) {
Text(forecast.headline).font(.headline)
HStack {
ForEach(forecast.days) { day in
DayCell(day: day)
}
}
Button("Open in App") {
// App-launching action wired via App Intents
}
}
.padding()
}
}
結果型別的ShowsSnippetView一致性會告訴系統將SwiftUI檢視與對話一同呈現。片段是互動式的:其中的按鈕可觸發其他App Intents、使用者可捲動、檢視也參與系統的互動層。
值得使用互動式片段的情境包括:天氣預報、行事曆事件、交通時刻、運動賽事比分、包裹追蹤。任何使用者期望從系統介面獲得超過單行對話回應的場合都適用。
實體檢視註解
實體檢視註解讓App能宣告AppEntity應如何在不同系統情境下呈現5。此機制以多重變體擴充DisplayRepresentation:
struct Recipe: AppEntity {
var displayRepresentation: DisplayRepresentation {
DisplayRepresentation(
title: "\(title)",
subtitle: "\(cuisine) - \(time) min",
image: .init(named: imageName)
)
}
}
傳統模型回傳單一的DisplayRepresentation。iOS 26讓實體能提供針對情境的特定變體,讓系統根據呈現位置(精簡清單、主視覺卡片、Spotlight結果、視覺智慧面板)挑選適當變體。框架會依情境挑選正確的變體,而App只需宣告每一個。
此模式支援需要在不同情境(例如緊湊的Spotlight清單與單卡片視覺智慧回應)間呈現不同實體外觀的App。各變體可組合使用,App無須自行偵測情境。
與既有App Intents的組合運用
iOS 26的新增內容可與既有的App Intents原語組合運用:
- App的
AppShortcutsProvider(於無障礙作為平台中介紹)為語音、動作按鈕與Spotlight註冊捷徑。 - 每個
AppShortcut參照一個AppIntent,後者擁有從使用者請求中解析出的@Parameter屬性。 AppIntent.perform()方法回傳的結果型別可包含片段檢視(ShowsSnippetView)或對話(ProvidesDialog)。- 意圖參數所參照的
AppEntity類型現可支援@DeferredProperty與實體檢視註解。 - 新的
IntentValueQuery類型讓相同實體得以出現在視覺智慧中。
整體形貌:保留既有模型;iOS 26的工作是在同一個實體介面上新增類型(查詢)與註解(延遲、檢視變體)。
常見失誤
App Intents 2.0採用失誤的三種模式:
IntentValueQuery回傳未經篩選的結果。 不論相關性如何,只要符合描述符搜尋詞就全部回傳的查詢,會稀釋視覺智慧體驗。修正方式:對查詢進行篩選(前N相關性、依時間加權、依使用者個人化),讓每個回傳的實體都對得起它在系統UI中的位置。
為快速值使用@DeferredProperty。 延遲機制是為真正昂貴的運算而設計。將快速的記憶體內屬性標記為延遲,只會增加非同步額外負擔卻無實質好處。修正方式:將@DeferredProperty保留給延遲後真正能帶來效益的屬性(伺服器擷取、大量運算、ML模型呼叫)。
像完整App的互動式片段。 片段是緊湊的UI介面;將其當作迷你App處理會產生擁擠或渲染緩慢的片段。修正方式:讓片段聚焦於即時回應與一兩個相關動作;使用「Open in App」按鈕將複雜流程交給完整App處理。
此模式對iOS 26+ App的意義
三個重點。
-
任何具備視覺內容的App都應加入
IntentValueQuery。 購物、食譜、產品、地點、可識別物體。視覺智慧整合是新的探索介面;不參與的App在那裡形同隱形。 -
為昂貴的實體欄位使用
@DeferredProperty。 詳細描述、運算指標、伺服器擷取資料。預設非同步的模式契合現代Swift程式碼,並讓便宜的實體回傳保持快速。 -
為高價值查詢類型採用互動式片段。 天氣、行事曆、交通、運動、包裹追蹤。當單行對話不夠用、但啟動完整App又太過頭時,片段UI能讓使用者繼續停留在系統回應介面。
完整的Apple生態系列:型別化的App Intents;MCP伺服器;路由問題;Foundation Models;執行階段與工具LLM的區別;三種介面;單一真實來源模式;兩個MCP伺服器;Apple開發的hooks;Live Activities;watchOS執行階段;SwiftUI內部;RealityKit的空間心智模型;SwiftData結構紀律;Liquid Glass模式;多平台發佈;平台矩陣;Vision框架;Symbol Effects;Core ML推論;Writing Tools API;Swift Testing;Privacy Manifest;無障礙作為平台;SF Pro字體系統;visionOS空間模式;Speech框架;SwiftData遷移;tvOS焦點引擎;@Observable內部;SwiftUI Layout通訊協定;自訂SF Symbols;AVFoundation HDR;watchOS workout生命週期;我拒絕撰寫的主題。系列總目錄位於Apple生態系列。如需更廣泛的iOS結合AI代理情境,請參閱iOS Agent開發指南。
常見問答
測試IntentValueQuery需要啟用Apple Intelligence嗎?
完整的視覺智慧測試需要。視覺智慧需要支援Apple Intelligence的硬體(iPhone 15 Pro或更新機種、M1 Mac或更新機種)、iOS 26+並啟用Apple Intelligence。在開發階段,您可以直接建構SemanticContentDescriptor並呼叫查詢的values(for:)方法,在單元測試中測試查詢,無須完整的系統堆疊。
@DeferredProperty可以擲出例外嗎?
可以。非同步getter簽章為get async throws,例外會傳播至系統。系統會以不顯示延遲屬性值的方式呈現實體(或在某些情境下顯示錯誤狀態)來處理失敗。App應優雅地失敗並回傳有意義的錯誤狀態,而非當機。
互動式片段的內容支援動畫嗎?
支援,搭配標準的SwiftUI動畫原語。片段檢視在系統的回應介面中執行,該介面支援與App內SwiftUI相同的動畫基礎架構。建議參考系列中的Symbol Effects文章,了解符合平台慣例的動畫語彙。
實體檢視註解如何與Widget互動?
Widget是獨立的WidgetKit介面;實體檢視註解作用於App Intents情境(Spotlight、視覺智慧、Siri回應)。對於同時將相同資料以AppEntity與Widget形式呈現的App,這兩種介面需要分別宣告UI。App通常共用底層資料模型,並為每個介面撰寫精簡的呈現檢視。
此功能與MCP工具的關係為何?
App Intents是Apple Intelligence的意圖介面;MCP工具則是通用LLM的代理-伺服器通訊協定。iOS 26將視覺智慧加入App Intents(Apple的介面)。對於非Apple的代理(Claude、GPT等級),在本機或遠端執行的MCP工具涵蓋相同概念領域。系列中的App Intents與MCP工具對比探討此路由問題。
IntentValueQuery可以與EntityQuery組合使用嗎?
可以。兩者服務不同介面:EntityQuery用於使用者輸入或唸出實體名稱時(Spotlight、Siri);IntentValueQuery用於使用者位於含有影像情境的視覺智慧中。App的AppEntity可同時註冊兩種查詢;系統會根據情境挑選適當的一個。
參考資料
-
Apple Developer Documentation:App Intents。涵蓋
AppIntent、AppEntity、查詢、參數及iOS 26新增內容的框架參考。 ↩ -
Apple Developer:Explore new advances in App Intents(WWDC 2025議程275)。介紹
IntentValueQuery、SemanticContentDescriptor與視覺智慧整合。 ↩↩ -
Apple Developer Documentation:
@DeferredProperty()。為iOS 26 App Entities引入的非同步運算實體屬性巨集。內容涵蓋於WWDC 2025議程275(Explore new advances in App Intents)。 ↩ -
Apple Developer Documentation:透過
ShowsSnippetView結果型別結合在系統情境(Spotlight、視覺智慧、Siri回應區)中渲染的SwiftUI檢視所建立的互動式App Intents片段。 ↩ -
Apple Developer Documentation:
DisplayRepresentation與實體檢視註解。用於宣告AppEntity在不同系統情境下如何呈現的機制。 ↩