App Intents u iOS 26: Vodič za Siri, Shortcuts i Apple Intelligence
App Intents u iOS 26 omogućuje da jedan Swift tip radi kao Siri naredba, interaktivni widget i Apple Intelligence akcija. Kompletan vodič s primjerima za Swift 6.
App Intents je Appleov moderni okvir koji vam dopušta da funkcionalnosti iOS aplikacije izložite Siri, Shortcuts aplikaciji, Spotlightu, widgetima i Apple Intelligenceu, i to bez pisanja Intent Definition datoteka. U iOS 26 taj je okvir dobio novi AssistantSchema sustav, snippet UI komponente i tijesnu integraciju s Apple Intelligence akcijama. Praktično: jedan Swift tip može istovremeno raditi kao glasovna naredba, interaktivni widget i AI‑pokretana automatizacija. U ovom vodiču pokazat ću vam kako se sve to slaže u produkciji, korak po korak.
App Intents zamjenjuju stari SiriKit i Intents Extension pristup. Sve pišete u Swiftu, bez .intentdefinition datoteka.
Novi AssistantSchema u iOS 26 omogućuje Apple Intelligenceu da automatski otkrije i pozove vaše akcije preko Siri‑ja i alata za pisanje.
Jedan AppIntent tip radi kao Siri naredba, Shortcuts akcija, Focus filter, App Shortcut, interaktivni widget i Control Center kontrola.
App Shortcuts automatski se pojavljuju u Spotlightu i Siri‑ju bez korisničke konfiguracije. Postavljate ih statički u AppShortcutsProvider.
Snippet UI (nova SwiftUI komponenta SnippetView) prikazuje bogati rezultat izravno u Siri‑ju ili Spotlightu, bez otvaranja aplikacije.
Za performanse: koristite @Dependency za dijeljenje pohrane, izbjegavajte cold‑start scenarije i grupirajte srodne parametre.
Što je App Intents framework?
App Intents je deklarativni okvir koji je Apple predstavio na WWDC 2022 kao nasljednika SiriKita i Intents Extensiona, a u iOS 26 doživljava treću veliku iteraciju. Umjesto pisanja XML sličnih .intentdefinition datoteka, definirate obične Swift tipove koji potvrđuju protokol AppIntent. Sustav zatim automatski generira metapodatke za Siri, Shortcuts, Spotlight, Focus filtere, interaktivne widgete i Apple Intelligence.
U produkciji sam ovaj pristup prvi put ozbiljno koristio na Wealth timu u Revolutu, gdje smo Shortcuts akcije za praćenje portfelja migrirali sa SiriKita na App Intents u nekoliko dana. Dio koji je prije bio Intents Extension s tisuću redaka boilerplate koda sveden je na tri Swift datoteke. Iskreno, to je bio jedan od onih trenutaka kad shvatiš zašto je Apple ovoliko dugo forsirao migraciju.
U iOS 26 dobili smo tri nove sposobnosti: AssistantSchema makro za AI otkrivanje, SnippetView za bogate rezultate te znatno bolju podršku za asinkrone tijekove kroz Swift 6 Sendable provjere. Konceptualno, App Intents se sastoji od pet gradbenih blokova koji zajedno pokrivaju sve dodirne točke Appleove platforme: AppIntent (akcija koja se izvršava), AppEntity (podatkovni model koji sustav razumije), AppEnum (nabrajanje vrijednosti), AppShortcut (statički unaprijed konfigurirana kratica) i AppIntentsPackage (namespace za dijeljenje između ciljeva). Sve što slijedi u ovom vodiču kombinira te blokove.
Kako izraditi App Intent u Swiftu 6
Najjednostavniji App Intent zahtijeva samo jedan Swift tip s title, description i perform() metodom. Slijedi minimalni primjer akcije koja bilježi novi trenutak raspoloženja u aplikaciji za praćenje navika.
import AppIntents
import SwiftData
struct LogMoodIntent: AppIntent {
static let title: LocalizedStringResource = "Zabilježi raspoloženje"
static let description = IntentDescription(
"Zapisuje trenutno raspoloženje u dnevnik navika.",
categoryName: "Praćenje"
)
// Otvara aplikaciju samo ako trebamo prikazati UI.
static let openAppWhenRun: Bool = false
@Parameter(title: "Raspoloženje")
var mood: MoodLevel
@Parameter(title: "Bilješka", default: "")
var note: String
@Dependency private var store: MoodStore
func perform() async throws -> some IntentResult & ProvidesDialog {
try await store.append(mood: mood, note: note, at: .now)
return .result(
dialog: "Zabilježeno: \(mood.rawValue). Odličan posao!"
)
}
}
Nekoliko važnih detalja koje često promašim kad radim brzu izmjenu: title mora biti LocalizedStringResource (ne obična String) da bi Siri pravilno prikazao naredbu na hrvatskom, francuskom ili bilo kojem drugom jeziku. perform() je async throws, što znači da se prirodno uklapa u Swift Concurrency model s async/await i strukturiranom konkurentnošću. U Swiftu 6 kompajler će vas natjerati da svaki @Parameter tip bude Sendable, pa ako koristite prilagođene tipove, dodajte tu potvrdu ranije. Vjerujte mi, kasnije popravljanje concurrency grešaka u već pisanom kodu nije zabavan posao.
@Dependency je novost iz iOS 17 koja se u iOS 26 znatno stabilizirala. Dopušta injektiranje dijeljenih instanci (SwiftData konteksta, mrežnih klijenata, autentikacijskog stanja) bez singletona. Ovisnost registrirate u App tipu putem AppDependencyManager.shared.add { MoodStore() } tijekom pokretanja procesa aplikacije.
Parametri, entiteti i IntentParameter
App Intents parametri su tipizirani i deklarativni. Osnovni tipovi (String, Int, Double, Date, URL, Measurement) rade odmah. Za domenski specifične vrijednosti kreirate AppEnum ili AppEntity. Evo primjera enumeracije koja Siri‑ju izlaže tri razine raspoloženja.
Za bogatije modele, recimo kada Siri treba pretraživati postojeće entitete u vašoj bazi, implementirajte AppEntity. Sustav tada automatski nudi opcije korisniku kroz Shortcuts editor ili glasovno pitanje "koji unos?".
struct HabitEntity: AppEntity, Identifiable {
let id: UUID
let name: String
let streak: Int
static let typeDisplayRepresentation: TypeDisplayRepresentation = "Navika"
var displayRepresentation: DisplayRepresentation {
DisplayRepresentation(
title: "\(name)",
subtitle: "Niz: \(streak) dana"
)
}
static let defaultQuery = HabitQuery()
}
struct HabitQuery: EntityQuery {
@Dependency private var store: HabitStore
func entities(for identifiers: [UUID]) async throws -> [HabitEntity] {
try await store.habits(matching: identifiers)
}
func suggestedEntities() async throws -> [HabitEntity] {
try await store.recent(limit: 5)
}
}
Ovaj obrazac je moćan zato što isti HabitEntity možete koristiti u tri App Intenta (dodaj, ukloni, prikaži), a Siri automatski nudi ista predlaganja u sva tri konteksta. U iOS 26 EntityQuery je dobio EntityStringQuery varijantu koja podržava fuzzy pretraživanje po korisničkom upitu. To je presudno za glasovne naredbe, gdje se prepoznavanje ne poklapa uvijek točno s pohranjenim nazivom.
App Shortcuts, Siri i Spotlight integracija
App Shortcuts su statički definirane kratice koje se pojavljuju u Siri, Spotlight i Shortcuts aplikaciji čim korisnik instalira vašu aplikaciju, bez ikakve konfiguracije s njihove strane. To je najvažniji razlog zašto uopće pišete App Intents: dobivate besplatnu vidljivost u sustavu.
struct MoodAppShortcuts: AppShortcutsProvider {
static var appShortcuts: [AppShortcut] {
AppShortcut(
intent: LogMoodIntent(),
phrases: [
"Zabilježi raspoloženje u \(.applicationName)",
"Dodaj unos raspoloženja u \(.applicationName)"
],
shortTitle: "Zabilježi raspoloženje",
systemImageName: "heart.text.square"
)
AppShortcut(
intent: ShowStreakIntent(),
phrases: [
"Prikaži moj niz u \(.applicationName)"
],
shortTitle: "Moj niz",
systemImageName: "flame"
)
}
static let shortcutTileColor: ShortcutTileColor = .orange
}
Nekoliko pravila iz iskustva: prva fraza mora sadržavati \(.applicationName) tokenu jer Siri koristi to za razrješavanje aplikacije, ograničeni ste na 10 App Shortcuta po aplikaciji, i sve fraze moraju biti lokalizirane preko AppShortcuts.strings datoteke. Za Spotlight, sustav automatski indeksira shortTitle i systemImageName. Ako želite indeksirati stvarne entitete (recimo, sve navike), koristite CSSearchableIndex s indexAppEntities() metodom uvedenom u iOS 17.
Apple Intelligence i AssistantSchema u iOS 26
Najznačajnija novost u iOS 26 je proširenje App Intentsa AssistantSchema makroom, koji omogućuje Apple Intelligenceu da vaše akcije koristi izvorno unutar sustava za pisanje, Siri konverzacija i ekstenzija u Mail, Notes i Messages aplikacijama. Ideja je jednostavna: Apple je definirao ograničen skup standardnih shema (poput SendMessageIntent, CreateNoteIntent, PlayMediaIntent) i ako vaš intent potvrđuje jednu od njih, AI ga može automatski odabrati na temelju konteksta.
@AssistantIntent(schema: .journal.createEntry)
struct CreateJournalEntryIntent: AppIntent {
static let title: LocalizedStringResource = "Novi unos u dnevnik"
@Parameter(title: "Sadržaj")
var content: String
@Parameter(title: "Datum", default: Date())
var date: Date
func perform() async throws -> some IntentResult {
try await JournalStore.shared.create(content: content, at: date)
return .result()
}
}
Kad Apple Intelligence primi zahtjev poput "Dodaj u moj dnevnik: danas sam završio maraton", sustav automatski usmjerava taj tekst prema svim intentima koji potvrđuju .journal.createEntry shemu, korisnik bira aplikaciju, i vaš perform() se izvršava. Prema Appleovoj dokumentaciji, u vrijeme pisanja postoji preko 100 shema u 15 domena: Books, Browser, Camera, Files, Journal, Mail, Photos, Presentation, Spreadsheet, System, Notes, Word Processor i druge.
Interaktivni widgeti i Control Center kontrole
Od iOS 17 widgeti mogu izravno pozivati App Intente kroz Button(intent:) i Toggle(isOn:intent:), i to bez otvaranja aplikacije. U iOS 26 to je prošireno na Control Center kroz ControlWidget protokol i Lock Screen alate. Rezultat je da isti LogMoodIntent iz prvog primjera može biti gumb na Home Screen widgetu, prekidač u Control Centeru ili unos u Focus filter, bez ijednog dodatnog retka logike.
struct QuickMoodControl: ControlWidget {
var body: some ControlWidgetConfiguration {
StaticControlConfiguration(kind: "com.example.mood.quick") {
ControlWidgetButton(action: LogMoodIntent(mood: .great)) {
Label("Izvrsno", systemImage: "sun.max")
}
}
.displayName("Zabilježi izvrsno raspoloženje")
.description("Jednim dodirom iz Control Centera.")
}
}
Za širi kontekst kako se widgeti uklapaju u SwiftUI ekosustav, pogledajte naš vodič za SwiftUI ScrollView i paging u iOS 26. Mnoga ista načela projektiranja UI‑ja (rijetka učitavanja, minimalno stanje, izbjegavanje glavnog niti bloka) primjenjuju se i ovdje. Također, ako svoje intente izlažete kroz Lock Screen ili Standby način rada, provjerite da perform() završi ispod 500 ms, jer sustav prekida bilo koji intent koji traje dulje.
Snippet UI i bogati rezultati
U iOS 26 App Intents dobivaju novu SnippetView komponentu koja omogućuje vraćanje bogatog SwiftUI korisničkog sučelja izravno u Siri, Spotlight ili Shortcuts prikaz rezultata, bez otvaranja aplikacije. Do sada su rezultati bili ograničeni na dijalog teksta ili predefinirane IntentSnippetView šablone. Sada možete vratiti bilo koji SwiftUI pogled.
struct ShowStreakIntent: AppIntent {
static let title: LocalizedStringResource = "Prikaži moj niz"
@Dependency private var store: HabitStore
func perform() async throws -> some IntentResult & ShowsSnippetView {
let streak = try await store.currentStreak()
return .result(
view: StreakSnippet(days: streak.days, habit: streak.habit)
)
}
}
struct StreakSnippet: View {
let days: Int
let habit: String
var body: some View {
VStack(alignment: .leading, spacing: 8) {
Text(habit)
.font(.headline)
HStack {
Image(systemName: "flame.fill")
.foregroundStyle(.orange)
Text("^[\(days) dan](inflect: true) zaredom")
.font(.title2)
.bold()
}
}
.padding()
}
}
Pravila za snippete: koristite standardne SwiftUI kontrole (Text, Image, Stack, Chart), izbjegavajte NavigationStack jer sustav upravlja prezentacijom, i držite visinu ispod 300 pt jer se snippet renderira unutar Siri modalnog prikaza. Za grafikone koji prikazuju povijesne podatke, obratite pažnju na jednake principe koje smo obradili u vodiču za SwiftUI Charts u iOS 26.
Razlika između App Intents i SiriKit
Ovo je jedno od najčešćih pitanja koje dobivam na radionicama. Kratki odgovor: App Intents zamjenjuju SiriKit za sve nove aplikacije. SiriKit ostaje podržan samo za četiri stara domena (VoIP, Messaging, Payments, Ride Booking) gdje sustav zahtijeva potvrđivanje specifičnih protokola s dubokim OS integracijama. Za sve ostalo, a to je oko 95 % slučajeva, pišete App Intents.
Značajka
App Intents (iOS 26)
SiriKit (naslijeđeni)
Jezik definicije
Swift kod
.intentdefinition XML
Extension zahtjev
Ne (radi u glavnom procesu)
Da (Intents Extension)
Cold start latencija
~50 ms (bez extensiona)
~300 do 500 ms
Shortcuts editor
Automatski
Ograničeno
Interaktivni widgeti
Da
Ne
Apple Intelligence
Da (AssistantSchema)
Ne
Control Center
Da
Ne
Focus filteri
Da
Ne
Osobno preporučujem migraciju sa SiriKita čim vam projekt dopušta, i to ne samo zbog novih značajki. Uklanjanjem Intents Extensiona smanjujete veličinu binarnog paketa za oko 200 do 400 KB i skraćujete vrijeme pokretanja aplikacije jer sustav više ne mora dizati odvojeni proces prilikom prvog Siri zahtjeva.
Performanse i najbolje prakse
App Intents se izvršavaju unutar procesa vaše aplikacije, što znači da svaki hladni pokret intenta može pokrenuti punu inicijalizaciju aplikacije ako je proces prije bio ubijen. Kad sam u Revolutu radio na cold‑start optimizaciji koja je smanjila vrijeme pokretanja za 40 %, iste trikove primijenili smo i za App Intents put.
Odvajajte teške SDK inicijalizacije od perform() puta. Analitika, praćenje grešaka i A/B testiranje mogu ići u Task.detached(priority: .background) nakon što intent vrati rezultat.
Koristite @Dependency s lijenom inicijalizacijom. Registrirajte AppDependencyManager.shared.add { LazyStore() }, gdje LazyStore odgađa otvaranje baze podataka do prvog upita.
Grupirajte srodne intente kroz DynamicOptionsProvider. Umjesto tri odvojena intenta (dodaj, ukloni, ažuriraj), jedan intent s Action parametrom smanjuje broj metapodataka koje sustav mora indeksirati.
Mjerite s Instrumentima. Time Profiler predložak s "System Trace" opcijom pokazuje vam koliko vremena sustav troši od dodira na Shortcut do izvršenja vašeg perform(). Ciljam ispod 200 ms na iPhone SE 2. generacije, što je moj referentni najsporiji uređaj.
Za dublju analizu Sendable compliance i strogih concurrency provjera u Swiftu 6, koje su ključne za App Intents kod, kombinirajte ove smjernice s obrascima iz vodiča za Swift Macros u Swiftu 6. Makroi poput @AssistantIntent sami se oslanjaju na SwiftSyntax i produciraju kod koji mora zadovoljiti iste stroge concurrency provjere.
Često postavljana pitanja
Trebam li i dalje podržavati SiriKit?
Samo ako vaša aplikacija spada u jedan od četiri preostala SiriKit domena (VoIP, Messaging, Payments, Ride Booking) koji zahtijevaju specifične protokole. Za sve ostale slučajeve upotrijebite App Intents. Apple više ne preporučuje SiriKit za nove implementacije od iOS 16.
Podržavaju li App Intents SwiftData i Core Data?
Da. Preko @Dependency mehanizma možete injektirati SwiftData ModelContext ili Core Data NSPersistentContainer. Za SwiftData koristite ModelActor obrazac kako bi perform() ostao izoliran od glavne niti i zadovoljio Swift 6 concurrency provjere.
Kako testirati App Intents na simulatoru?
Otvorite Shortcuts aplikaciju na simulatoru, dodajte novu kraticu i odaberite vašu aplikaciju iz popisa. Sve App Shortcuts pojavljuju se automatski. Za Siri glasovno prepoznavanje potreban je fizički uređaj jer simulator ne podržava mikrofon za Siri obradu.
Koja je najmanja iOS verzija za App Intents?
Osnovni App Intents okvir dostupan je od iOS 16. Interaktivni widgeti zahtijevaju iOS 17, dok snippet SnippetView API i AssistantSchema makro zahtijevaju iOS 26. Za maksimalnu kompatibilnost koristite @available anotacije za noviju funkcionalnost.
Mogu li App Intents pozvati mrežni zahtjev?
Da, ali obratite pažnju na budžet vremena. Sustav prekida perform() ako traje dulje od 30 sekundi (10 sekundi za widget intente). Za dugotrajne operacije koristite BackgroundTasks okvir i vratite privremeni dijalog "Radim na tome, obavijestit ću vas kad završim".
Tomasz is a Krakow-based iOS engineer with 11 years of Swift experience. He spent four years at Revolut on the Wealth team, where he rewrote the trading charts in SwiftUI and shaved 40% off cold-start time by lazy-loading the analytics SDK. Before Revolut he was at Allegro, Poland's largest e-commerce platform, on the Seller Center iOS team.
His specialty is iOS performance work: Instruments deep-dives, memory-graph debugging, and figuring out why your scroll view drops frames only on iPhone SE 2nd-gen. He has contributed patches to swift-syntax and writes a quarterly newsletter for iOS engineers that covers under-discussed APIs like BackgroundTasks and NSFileCoordinator.
Tomasz holds the iOS App Development with Swift certification from Apple and occasionally runs paid workshops on Swift concurrency for in-house engineering teams in Europe.
Vodič za izradu Live Activities i Dynamic Island u iOS 26 pomoću ActivityKit okvira. Postavljanje Widget ekstenzije, ActivityAttributes, sva tri stanja Dynamic Islanda, App Intents i testiranje u Xcode 26 simulatoru.
Praktičan vodič kroz TipKit u iOS 26: kako izraditi savjete, definirati pravila, koristiti TipGroup, sinkronizirati stanje preko iClouda i lokalizirati poruke uz radne SwiftUI primjere.
Naučite kako scrollTargetBehavior, scrollPosition, containerRelativeFrame i scrollTransition zamjenjuju stari ScrollViewReader i omogućuju moderne paging carousele u SwiftUI.