iOS 27 的 App Intents:背景執行、跨裝置同步與 Spotlight
App Intents 隨 iOS 16 推出,是 Apple 為 Shortcuts、Siri 與 Spotlight 打造的型別化、結構化動作API;iOS 17 將它延伸到由 App Intents 驅動的小工具;iOS 18 讓它成為 Apple Intelligence 動作面的契約;iOS 26 又把它推進到 Visual Intelligence 與互動式片段。到了 iOS 27,這個賭注的形狀再次改變,而且這次的改變是機制層面的,而非表面妝點:一個 intent 現在可以執行超過 30 秒的背景時限、一個 entity 可以攜帶能跨越使用者各裝置而存續的身分,而一個 query 可以在系統提出要求時修復自己的 Spotlight 索引。iOS 27 增加的是能力,不是糖衣。1
過去每一次發行,拓寬的都是誰能呼叫您的 intent。iOS 27 拓寬的則是您的 intent 一旦被呼叫後能做什麼。一個處理數千筆記錄的同步 intent,過去得跟 30 秒倒數計時器賽跑而落敗;如今它能向系統要求更多執行空間,並在工作的同時回報進度。一個在 iPhone 上代表某物、在 Mac 上卻代表另一物的 entity,如今在兩者上都解析到同一個物件。本文將對照 Apple 的文件逐一檢視 iOS 27 的這片新天地,並沿用本系列其餘文章一貫的視角:一個已經出貨 App Intents 的 app,要取得每項新能力得補上什麼。
重點摘要
LongRunningIntent將 intent 的背景執行時間延伸到系統 30 秒限制之外。您把工作包進performBackgroundTask(options:operation:),並傳入LongRunningTaskOptions;該協定精煉自ProgressReportingIntent,因此回報進度是必要條件,而非選項。Live Activities 會自動呈現該進度。234SyncableEntity宣告某個AppEntity攜帶一個跨使用者各裝置一致的識別碼,讓系統能在 iPhone、Mac 與 Watch 上指向同一個物件(Siri 用它把對話從一台裝置交接到另一台)。5IndexedEntityQuery為EntityQuery加上 Spotlight 重新索引支援,因此當系統標記出您 app 索引的問題時,它能要求您的 query 重新捐獻受影響的 entity。6AppUnionValue與AppUnionValueCasesProviding(由@UnionValue巨集產生)讓單一參數接受數種不同的 entity 型別,並具備妥當的選擇器 UI 與參數摘要。78OwnershipProvidingEntity、EntityOwnership與EntityCollection涵蓋了具所有權意識的確認與批次效率;RunSystemShortcutIntent與IntentExecutionTargets則涵蓋了由小工具啟動的系統動作,以及由哪個行程執行 intent。910111213
30 秒之牆:LongRunningIntent
背景執行限制一直是 App Intent 能力的隱形天花板。當系統在背景執行某個 intent(使用者請 Siri 同步,接著鎖定手機放進口袋)時,傳統上大約只給 30 秒完成。2 對記錄喝了一杯水而言,這很充裕。但對同步一整個資料庫、執行裝置端推論,或處理一個大型檔案而言,30 秒形同一把鍘刀:系統在寫到一半時就終結了任務,使用者拿到的是個只完成一半的結果。
iOS 27 引入 LongRunningIntent,一個 intent 採用後即可向系統要求延長背景時段的協定。2 Apple 在文件中直接點名了適用情境:檔案操作、資料同步、機器學習推論,以及對足夠大的資料集進行的資料處理。光是宣告本身,就在您寫下第一行程式碼之前告訴了您最重要的約束:
protocol LongRunningIntent : ProgressReportingIntent
LongRunningIntent 精煉自 ProgressReportingIntent。2 你無法在不一併回報進度的前提下採用這個長時間執行協定,這是設計使然。延長的執行時間是系統有條件授予的特權,而條件就是你得持續告訴它你進行到哪了。一旦停止回報,系統就可以撤回延長並提早結束任務。3
工作放進 performBackgroundTask(options:operation:) 之中:
@discardableResult
func performBackgroundTask<T>(
options: LongRunningTaskOptions = [],
operation: @escaping () async throws -> T
) async throws -> T
您從 intent 的 perform() 主體呼叫此方法,並把昂貴的程式碼放進 operation 閉包。在會施加限制的平台上,此方法會自動把您的執行時間延伸到標準 30 秒限制之外;您不必自己啟動另一個背景任務,也不必管理 UIBackgroundTaskIdentifier。3 一個資料庫同步 intent 看起來是這樣:
import AppIntents
struct SyncLibraryIntent: LongRunningIntent {
static var title: LocalizedStringResource = "Sync Library"
func perform() async throws -> some IntentResult {
try await performBackgroundTask(options: []) {
let records = try await server.fetchPendingRecords()
for (offset, record) in records.enumerated() {
try await store.apply(record)
progress.completedUnitCount = Int64(offset + 1)
progress.totalUnitCount = Int64(records.count)
}
return ()
}
return .result()
}
}
有兩件事值得說明,因為教學文章往往略過它們。
progress 屬性是契約,不是遙測資料。 Apple 講得很明白:在 operation 執行期間,要定期更新來自 ProgressReportingIntent 一致性的 Progress,若不這麼做,系統可以取消執行時間的延長並提早結束任務。3 在一般 intent 上回報進度是錦上添花。在 LongRunningIntent 上,它是讓延長持續存活的心跳。
LongRunningTaskOptions 宣告資源需求。 這個選項值(一個 OptionSet 風格、預設為 [] 的結構)告訴系統此任務有哪些額外資源需求,系統會把這納入它授予的執行時間考量。4 空集合是常見情形。當工作需要超過預設配置時,才需要動用明確的選項。
突破 30 秒之外還有額外的好處:Live Activities 會免費呈現進度。文件指出,Live Activities 會運用它從 performBackgroundTask 自動收到的資訊來顯示 intent 任務的進度,並從您程式碼回報的值繪出標題、副標題與進度條。3 一個由語音啟動的長時間同步,會以即時進度條的形式出現在鎖定畫面上,而您完全不必為它打造任何一個 Live Activity 視圖。intent 負責回報,系統負責呈現。
LongRunningIntent 撐過 30 秒限制,並在 Live Activity 上附帶一個停止按鈕,讓使用者隨時都能取消。
在第 345 場議程中,Apple 針對一個真實的失敗案例示範 LongRunningIntent——一個老是在 30 秒視窗內陣亡的照片上傳——並展示系統如何管理背景任務的生命週期,同時以 Live Activity 的形式浮現進度與一個取消控制項。14
一致的身分:SyncableEntity
AppEntity 有一個 id。在單一裝置上,這個識別碼只需在 app 範圍內唯一即可。麻煩從使用者擁有不只一台裝置那一刻開始——而在 Apple 的生態系裡,這是常態。使用者在 iPhone 上與 Siri 討論的「Project Atlas」,當他在 Mac 上接續對話時,必須能被辨認為同一個「Project Atlas」。如果 iPhone 的本地識別碼與 Mac 的不同,系統手上就是兩個毫不相干的物件,無從連結。
SyncableEntity 是 iOS 27 的解答:5
protocol SyncableEntity : AppEntity
採用它,即宣告您 entity 的識別碼在各裝置間是相同的。這個協定的存在,告訴系統它能從一台裝置一致地指向您的 entity 到另一台裝置。Apple 給出了具體的好處:Siri 運用這項能力把一段對話從一台裝置轉移到另一台。5
採用的成本完全取決於您的識別碼從何而來。如果您的 entity 本來就使用一個穩定的跨裝置識別碼(一個伺服器發放的 UUID、一個 iCloud 記錄名稱),那麼採用 SyncableEntity 不需做其他任何更動,因為您早已儲存的值,正是系統所需要的值。5
import AppIntents
struct ProjectEntity: SyncableEntity {
static var typeDisplayRepresentation: TypeDisplayRepresentation = "Project"
static var defaultQuery = ProjectQuery()
// A UUID issued by the backend and identical on every device.
var id: UUID
var displayRepresentation: DisplayRepresentation {
DisplayRepresentation(title: "\(name)")
}
@Property(title: "Name") var name: String
}
陷阱在於那種會在每台裝置上各鑄造一個全新本地識別碼的 app(一個自動遞增的列 ID、一個每次安裝各自的 UUID)。那些識別碼在本地唯一,跨裝置卻毫無意義。Apple 對這種情形的建議是:採用此協定,並把您的身分繫於那個實際上穩定的值,好讓系統有個耐久之物可以錨定。5 同步一直是各團隊用自家 iCloud 管線親手反覆解決的難題。SyncableEntity 把跨裝置身分的宣告搬進了框架之中,讓 Siri 與系統其餘部分能據此行動。
自我修復的搜尋:IndexedEntityQuery
iOS 16 讓您把 IndexedEntity 實例捐獻給 Spotlight,使個別 entity 變得可搜尋。缺口在於修復。索引會漂移、會損毀,或在一次遷移之後落後,而在 iOS 27 之前,系統唯一的補救之道就是仰賴您 app 的 CSSearchableIndex 委派物件或其 CSImportExtension。
IndexedEntityQuery 透過讓系統要求您的query來重新索引,補上了這道缺口:6
protocol IndexedEntityQuery : EntityQuery where Self.Entity : IndexedEntity
where 子句即是前提條件:該 query 的 entity 必須遵循 IndexedEntity,因為重新索引唯有對那些您本來就捐獻給 Spotlight 的 entity 才有意義。6 當系統碰上某個 app 索引的問題時,如果您的 query 型別採用了這個協定,它就會呼叫該協定的方法;如果您的 query 沒有採用,Spotlight 就會繼續要求您的 CSSearchableIndex 物件(或您的 CSImportExtension,前提是您是透過將 entity 與該型別關聯來捐獻的)代為完成這項工作。6 您實作這些方法以取回所要求的 entity,並透過您偏好的可搜尋索引再次捐獻它們。
import AppIntents
import CoreSpotlight
struct PhotoQuery: IndexedEntityQuery {
func entities(for identifiers: [Photo.ID]) async throws -> [Photo] {
try await library.photos(matching: identifiers)
}
func suggestedEntities() async throws -> [Photo] {
try await library.recentPhotos(limit: 20)
}
// Called by the system during reindexing. Fetch the requested
// entities and donate them again to Spotlight.
func entities(matching string: String) async throws -> [Photo] {
try await library.photos(matchingText: string)
}
}
其價值在於營運層面。一個把 IndexedEntityQuery 做對的 app,會參與 Spotlight 的復原迴圈:系統察覺索引出錯,app 便按需供應新鮮資料,而不是讓使用者悄悄地流失搜尋結果,直到下一次完整重新捐獻為止。本系列的App Intents 基礎篇涵蓋了用以讓條目可搜尋的赤裸 IndexedEntity 揭露;IndexedEntityQuery 則是疊在其上的維護層。
一個參數,數種型別:AppUnionValue
不少真實的 intent,其某個參數合理地會是數種型別之一。「分享這個」,而「這個」是一張照片、一份文件,或一個連結。iOS 27 之前的權宜之計都很醜陋:每種型別各寫一個 intent,或一個字串判別子外加選擇器 UI 無法乾淨呈現的選用參數。
iOS 27 為型別化的聯集參數加入了 AppUnionValue:7
protocol AppUnionValue : TypeDisplayRepresentable
一個遵循此協定的聯集值,能作為帶有豐富中繼資料的 Shortcuts 參數運作,因此系統能在各成員型別之間呈現恰當的選擇器與合宜的參數摘要。7 您不必親手撰寫這份一致性。@UnionValue 巨集會產生它,而同一個巨集還會產生一個遵循 AppUnionValueCasesProviding 的巢狀 Cases 列舉:78
protocol AppUnionValueCasesProviding : AppEnum
AppUnionValueCasesProviding 由巨集所發出的 Cases 列舉自動遵循。8 它把這個 cases 列舉橋接回聯集值型別,並透過其 AppEnum 一致性繼承中繼資料,這正是讓每個 case 在選擇器中得到其顯示名稱的來源。8 實務上,您撰寫這個聯集並為它加上註解:
import AppIntents
@UnionValue
enum ShareTarget {
case photo(PhotoEntity)
case document(DocumentEntity)
case link(URL)
}
struct ShareIntent: AppIntent {
static var title: LocalizedStringResource = "Share Item"
@Parameter(title: "Item")
var target: ShareTarget
func perform() async throws -> some IntentResult {
// Switch over the concrete case and act accordingly.
return .result()
}
}
@UnionValue 巨集會處理 AppUnionValue 與 AppUnionValueCasesProviding 兩份一致性;若您想要超出預設的自訂中繼資料,可在一個擴充中實作協定的要求。7 一個參數、三種有效型別、一個懂得如何把三者全都呈現出來的選擇器。
所有權與效率
兩件各自獨立的 iOS 27 議題共用這一節,因為兩者都在防止系統對您的資料草率行事:具所有權意識的確認,以及批次操作的效率。
確認破壞性動作:OwnershipProvidingEntity
當您的 app 把 entity 傳入 intent 並從結果中回傳它們時,Apple Intelligence、Siri 與自訂捷徑都能跨 app 對那些 entity 行動。對於破壞性或敏感的動作(刪除一個 entity、更新一個共享的 entity),您會希望有一個帶著正確情境的確認。OwnershipProvidingEntity 提供了它:9
protocol OwnershipProvidingEntity : AppEntity
讓您的 entity 遵循它,當某個 intent 對共享或可公開存取的 entity 行動時,系統便會在對話框中帶著恰當情境提示確認。9 所有權狀態本身是一個 EntityOwnership 值,一個基於旗標的結構,您可在其中指定單一狀態,或用 OptionSet 組合數個狀態:10
import AppIntents
struct AlbumEntity: OwnershipProvidingEntity {
static var typeDisplayRepresentation: TypeDisplayRepresentation = "Album"
static var defaultQuery = AlbumQuery()
var id: UUID
var isSharedWithFamily: Bool
var isPublished: Bool
var displayRepresentation: DisplayRepresentation {
DisplayRepresentation(title: "\(name)")
}
@Property(title: "Name") var name: String
// Reflect how the user has shared this album so the system can
// calibrate its confirmation dialog.
var ownership: EntityOwnership {
var state: EntityOwnership = []
if isSharedWithFamily || isPublished {
state = .shared
}
return state
}
}
這套機制對擁有共享內容的 app 最為要緊:一個您發布或與家人共享的相簿,理應產生比私人相簿更為謹慎的確認,而 OwnershipProvidingEntity 正是 entity 告訴系統孰為孰的方式。9
不犧牲記憶體的批次處理:EntityCollection
解析 entity 並非免費。當一個 intent 把數百個 entity 作為參數,在參數解析期間強迫系統把每個識別碼都解析成完整實例,可能在一個糟糕的時機耗掉可觀的時間與記憶體。EntityCollection 是解法:11
struct EntityCollection<Entity> where Entity : AppEntity
這個集合一開始只為每個 entity 儲存識別碼,並在您日後需要時提供取回完整實例的選項。11 當您持有許多識別碼時,把它當作變數型別來用;當一個 intent 要對一個大集合進行操作時,把它當作參數型別來用:
import AppIntents
struct DisableNotificationsIntent: AppIntent {
static var title: LocalizedStringResource = "Disable Notifications"
// Hundreds of conversations resolve lazily, not all at once.
@Parameter(title: "Conversations")
var conversations: EntityCollection<ConversationEntity>
func perform() async throws -> some IntentResult {
return .result()
}
}
對一個持有數百個 entity 的參數而言,略過逐一識別碼的解析,恰好在使用者正等著動作開始的那一刻省下時間與記憶體。11
intent 在何處執行:RunSystemShortcutIntent 與 IntentExecutionTargets
兩項較小的 iOS 27 新增功能補完了這片天地。RunSystemShortcutIntent 是一個僅供小工具使用的 intent,用以從小工具按鈕啟動另一個 app,或執行一個 App Shortcut、自訂捷徑或系統動作:12
struct RunSystemShortcutIntent
您只用它來以系統捷徑初始化器初始化一個 Button,並把該按鈕放進小工具;在那個情境之外它毫無用處。12 當使用者設定該小工具時,他們選擇按鈕的動作,而 intent 供應系統在設定 UI 中所需的中繼資料。它並不交給您的小工具存取某捷徑的動作、參數或實作。如果所選的捷徑需要提示輸入,系統可能會開啟 Shortcuts app 來執行它。12
IntentExecutionTargets 回答了一個問題——這問題在您透過 Swift 套件或框架,於您的 app、小工具擴充與 App Intents 擴充之間共享 intent 與 entity 後就會浮現:由哪個行程執行這個 intent?13
struct IntentExecutionTargets
預設情況下,系統會用任何可用的目標來執行 intent 或 entity query。13 您用 IntentExecutionTargets 來約束這一點。Apple 的範例是瀏覽器:新增一個書籤可以在 app 不可見時發生,所以 App Intents 擴充就行;但開啟一個新分頁唯有在 app 可見時才說得通,這需要 app 自己的行程。13 您宣告有效的目標,系統便尊重這個約束。
採用路徑
一個已經出貨 App Intents 的 app,可以漸進式地加上 iOS 27 的各項能力;沒有任何一項會重寫核心模型。
- 找出您最慢的 intent。 任何在做檔案 I/O、同步、裝置端推論或大型資料處理的 intent,都是
LongRunningIntent的候選。採用此協定,把工作移進performBackgroundTask(options:operation:),並全程回報progress。您就能得到突破 30 秒的執行時間與免費的 Live Activities 進度。23 - 稽核您的 entity 識別碼。 如果它們本來就跨裝置穩定(伺服器 UUID、iCloud 記錄名稱),就讓相關 entity 遵循
SyncableEntity並出貨。如果它們是逐裝置的,先修好身分,再讓它們遵循。5 - 為那些 entity 屬於
IndexedEntity的 query 加上IndexedEntityQuery。 它純粹是增添式的:這些方法唯有在系統需要重新索引時才會被呼叫,而您的搜尋結果會在索引漂移之中維持正確。6 - 用
@UnionValue收攏多型別參數。 任何您曾用分立的 intent 或一個判別子字串假冒聯集之處,這個巨集都給您一個乾淨的參數。7 - 以
OwnershipProvidingEntity標記共享的 entity,並把大集合參數改為EntityCollection。 前者改善確認的安全性,後者改善解析的效能。911
常見問答
一個 LongRunningIntent 在背景能執行多久?
Apple 記載的是它所抬升的下限,而非一個固定的上限。系統傳統上給一個背景任務大約 30 秒完成,而 LongRunningIntent(透過 performBackgroundTask(options:operation:))在會施加限制的平台上會自動把那個視窗延伸到標準限制之外。23 這個延長是有條件的:您得持續更新來自 ProgressReportingIntent 一致性的 Progress,而若您停止,系統就可以取消延長並提早結束您的任務。3 把回報進度當作換取額外執行時間的代價。
我必須回報進度才能使用 LongRunningIntent 嗎?
是的。LongRunningIntent 宣告為 protocol LongRunningIntent : ProgressReportingIntent,因此採用它就需要 ProgressReportingIntent 一致性及其 Progress。2 除了滿足編譯器之外,定期的進度更新會讓背景執行時間的延長持續存活,並餵養 Live Activities 從 performBackgroundTask 自動呈現的標題、副標題與進度條。3
SyncableEntity 在執行期實際改變了什麼?
它宣告您 entity 的識別碼在使用者各裝置間相同,讓系統能把該物件處理成處處皆同的單一 entity,而非各裝置分立的物件。5 Apple 點名的具體能力:Siri 能把關於該 entity 的一段對話從一台裝置轉移到另一台。如果您的識別碼本來就跨裝置穩定,您採用此協定無須做其他更動;如果它們是逐裝置的,先把身分重新錨定到一個穩定的值上。5
系統何時會呼叫 IndexedEntityQuery?
當它碰上您 app 的 Spotlight 索引問題,且您的 query 型別採用了 IndexedEntityQuery(其 entity 遵循 IndexedEntity)時。6 系統會呼叫該協定的方法,讓您取回受影響的 entity 並再次捐獻給 Spotlight。如果您的 query 沒有採用此協定,Spotlight 會退回去要求您的 CSSearchableIndex 物件,或您的 CSImportExtension(前提是您是透過該型別捐獻的)。6
為何要用 EntityCollection 而不用一個普通的 entity 陣列?
EntityCollection<Entity> 一開始只儲存每個 entity 的識別碼,並在需要時才取回完整實例。11 作為一個 intent 參數,它阻止系統在參數解析期間強迫每個識別碼都解析成完整實例,這對一個持有數百個 entity 的參數而言,會在一個可能很關鍵的時刻省下時間與記憶體。11 一個普通的 [Entity] 陣列則會急切地把一切都解析出來。
RunSystemShortcutIntent 能在小工具之外使用嗎?
不能。它的存在純粹是為了以系統捷徑初始化器初始化一個 Button,以便放進小工具,在其他情境中它不提供任何功能。12 它為小工具的設定 UI 浮現中繼資料並代表使用者所選的動作;它並不交給您的小工具或 app 存取底層捷徑的動作、參數或實作。12
完整的 Apple 生態系系列:型別化的 App Intents;iOS 26 的新增功能;對照 MCP 工具的路由問題;Foundation Models;全新的 Foundation Models 工具呼叫控制;執行期與工具LLM之別;三種面;單一真實來源模式;與 app 並存的 MCP 伺服器;Live Activities;watchOS 執行期;SwiftUI 內部機制;SwiftData 結構紀律;Liquid Glass 模式;多平台出貨;平台矩陣;Vision 框架;@Observable 內部機制;作為平台的無障礙。系列中樞在 Apple 生態系系列。若想了解更廣的 iOS 結合 AI 代理脈絡,請參閱 iOS 代理開發指南。
參考資料
-
Apple Developer Documentation:App Intents。涵蓋
AppIntent、AppEntity、query、參數,以及 iOS 27 新增功能的框架參考。 ↩ -
Apple Developer Documentation:
LongRunningIntent(iOS 27.0 beta)。「一個您用以延長執行長時間任務之 app intent 背景執行時間的介面。」宣告為protocol LongRunningIntent : ProgressReportingIntent;系統傳統上給背景任務最多 30 秒。 ↩↩↩↩↩↩↩ -
Apple Developer Documentation:
performBackgroundTask(options:operation:)(iOS 27.0 beta)。在背景以延長的時間執行 operation,突破標準 30 秒限制;需要定期的進度更新,否則系統可以取消延長;Live Activities 會自動呈現進度。 ↩↩↩↩↩↩↩↩↩ -
Apple Developer Documentation:
LongRunningTaskOptions(iOS 27.0 beta)。用以設定長時間任務的選項;宣告額外的資源需求,傳入performBackgroundTask(options:operation:)。 ↩↩ -
Apple Developer Documentation:
SyncableEntity(iOS 27.0 beta)。「一個指出您 entity 擁有跨裝置一致識別碼的介面。」宣告為protocol SyncableEntity : AppEntity;Siri 用它在裝置間轉移對話。 ↩↩↩↩↩↩↩↩ -
Apple Developer Documentation:
IndexedEntityQuery(iOS 27.0 beta)。「一個為您 entity query 加上 Spotlight 重新索引支援的介面。」宣告為protocol IndexedEntityQuery : EntityQuery where Self.Entity : IndexedEntity。 ↩↩↩↩↩↩↩ -
Apple Developer Documentation:
AppUnionValue(iOS 27.0 beta)。「一個為聯集值提供名義型別身分與中繼資料的協定。」宣告為protocol AppUnionValue : TypeDisplayRepresentable;一致性由@UnionValue巨集產生。 ↩↩↩↩↩↩ -
Apple Developer Documentation:
AppUnionValueCasesProviding(iOS 27.0 beta)。宣告為protocol AppUnionValueCasesProviding : AppEnum;由@UnionValue巨集產生的Cases列舉自動遵循。 ↩↩↩↩ -
Apple Developer Documentation:
OwnershipProvidingEntity(iOS 27.0 beta)。「一個為 app entity 向系統提供所有權與共享情境的型別。」宣告為protocol OwnershipProvidingEntity : AppEntity;對共享或可公開存取的 entity 提示確認。 ↩↩↩↩↩ -
Apple Developer Documentation:
EntityOwnership(iOS 27.0 beta)。「一個代表 app entity 所有權與共享特性的型別。」宣告為struct EntityOwnership;基於旗標,可用OptionSet組合。 ↩↩ -
Apple Developer Documentation:
EntityCollection(iOS 27.0 beta)。「一個 entity 識別碼的陣列,您用它來改善涉及大量 entity 之操作的效率。」宣告為struct EntityCollection<Entity> where Entity : AppEntity;一開始儲存識別碼,並惰性解析完整實例。 ↩↩↩↩↩↩↩ -
Apple Developer Documentation:
RunSystemShortcutIntent(iOS 27.0 beta)。「一個您在小工具中用以開啟另一個 app,或執行 App Shortcut、自訂捷徑或系統動作的 app intent。」宣告為struct RunSystemShortcutIntent;僅可用於初始化一個小工具Button。 ↩↩↩↩↩↩ -
Apple Developer Documentation:
IntentExecutionTargets(iOS 27.0 beta)。「一組描述由哪個行程執行 intent 或 entity query 的選項。」宣告為struct IntentExecutionTargets;把執行約束到 app、App Intents 擴充,或任何可用的目標。 ↩↩↩↩ -
Apple,WWDC26 第 345 場議程,「Discover new capabilities in the App Intents framework.」developer.apple.com/videos/play/wwdc2026/345。Apple 示範
LongRunningIntent化解一個老是在 30 秒限制內失敗的照片上傳 intent,由框架管理背景任務的生命週期,並以 Live Activity 的形式浮現進度與一個停止控制項。 ↩