Foundation Models Swiftissä: Käytännön opas Apple Intelligence -malliin (2026)
Käytännön opas Applen Foundation Models -kehyksen käyttöön Swiftissä: istuntojen luonti, strukturoitu tuotos @Generable-makrolla, streaming, työkalukutsut ja saatavuuden tarkistus iOS 26:ssa.
Foundation Models -kehys on Applen Swift-natiivi rajapinta, jonka kautta sovellukset voivat käyttää laitteessa suoritettavaa Apple Intelligence -kielimallia ilman verkkoyhteyttä tai palvelinkustannuksia. Kehys julkaistiin osana iOS 26:tta, iPadOS 26:tta ja macOS Tahoeta kesäkuussa 2025, ja se tarjoaa LanguageModelSession-tyypin promptaukseen, @Generable-makron strukturoituun tuotokseen sekä Tool-protokollan työkalukutsuihin. Olen pyörittänyt kehystä omissa sivuprojekteissani siitä lähtien, kun ensimmäiset Xcode 26 -betaversiot ilmestyivät, ja tämä artikkeli kokoaa ne asiat, jotka olisin halunnut tietää alussa.
Foundation Models -kehys vaatii Apple Intelligence -yhteensopivan laitteen: iPhone 15 Pro tai uudempi, iPad ja Mac M1-piiristä alkaen.
LanguageModelSession on rinnakkainen istunto-olio, joka säilyttää keskusteluhistorian automaattisesti.
@Generable-makro generoi malleille decoodausskeeman, joten respond(to:generating:) palauttaa tyypitetyn Swift-arvon ilman JSON-manuaalia.
Työkalukutsut toteutetaan Tool-protokollalla; malli päättää itse, milloin kutsuu työkalua argumenttien kanssa.
Tarkista aina SystemLanguageModel.default.availability ennen istunnon luontia, koska virheilmoitukset eivät paljasta syytä yhtä siististi.
Kehyksen on-device-malli on noin 3 miljardia parametria; älä yritä korvata sillä GPT-4-luokkaisia tehtäviä.
Mikä on Foundation Models -kehys?
Foundation Models on Applen ensimmäinen julkinen rajapinta omaan, laitteessa suoritettavaan suureen kielimalliin. Toisin kuin Core ML, joka on yleisen tason koneoppimisen ajoympäristö, Foundation Models on rakennettu nimenomaan tekstigeneroinnin, yhteenvedon, luokittelun ja työkalukutsujen ympärille. Malli itse ei ole sovelluksen niputtama tiedosto, vaan järjestelmäkomponentti, jonka käyttöjärjestelmä lataa ensimmäisellä Apple Intelligencen käyttökerralla ja päivittää itse.
Tämä on hieman samaa logiikkaa, mihin Apple totutti meidät jo Objective-C:n aikana NSLinguisticTaggerilla: sovellus ei kanna kielimallia mukanaan, vaan käyttää järjestelmän tarjoamaa. Erona on, että nyt taustalla on noin 3 miljardin parametrin transformer-malli LoRA-adaptereineen, ei sääntöpohjainen jäsentäjä. Kehyksen modulaarisuus tarkoittaa myös, että App Store -binäärin koko pysyy pienenä (kymmenien megatavujen mallitiedostoja ei kuljeteta mukana).
Kehyksen ytimessä ovat neljä tyyppiä: SystemLanguageModel kuvaa saatavilla olevaa mallia, LanguageModelSession on yksi keskustelu, Tool on protokolla mallin kutsumille funktioille, ja @Generable on makro, joka tekee omista Swift-tyypeistäsi mallin tuotoskelpoisia. Tarkka rajapinta on dokumentoitu osoitteessa Apple Developer: Foundation Models.
Mitkä laitteet tukevat Foundation Models -kehystä?
Foundation Models -kehys vaatii Apple Intelligence -yhteensopivuuden, joka rajoittaa käytön käytännössä uusimpiin laitteisiin. iPhonella tämä tarkoittaa iPhone 15 Prota, iPhone 15 Pro Maxia ja koko iPhone 16- ja 17-sarjaa. iPadeista mukana ovat M1-piirin tai uudemman sisältävät mallit, ja Maceista kaikki Apple silicon -koneet M1:stä alkaen. Tämän alle jäävillä laitteilla SystemLanguageModel.default.availability palauttaa .unavailable(.deviceNotEligible), jolloin sovelluksen on tarjottava vaihtoehtoinen reitti tai kerrottava käyttäjälle, että toiminto ei ole käytettävissä.
Lisäksi käyttäjän on kytkettävä Apple Intelligence päälle Asetuksista. Jos hän ei ole tehnyt niin, saat .unavailable(.appleIntelligenceNotEnabled). Tämä on todellisuudessa yleisempi virhe kuin laiterajoitus, koska ominaisuus on opt-in. Suositukseni: älä yritä avata Asetuksia automaattisesti. Selitä lyhyesti, miksi toiminto vaatii Apple Intelligencen, ja anna käyttäjän päättää.
watchOS- ja tvOS-tukea ei tällä hetkellä ole, eikä Apple ole sellaista vihjannut. visionOS 26 tukee kehystä Vision Pro -laitteissa, joissa on M2 tai uudempi.
Ensimmäinen LanguageModelSession
Yksinkertaisin mahdollinen käyttö näyttää tältä. Sessio luodaan, prompt lähetetään ja vastaus odotetaan. Koko rajapinta on async, joten se istuu luonnollisesti modernin Swift-rinnakkaisuuden päälle.
import FoundationModels
func summarize(_ text: String) async throws -> String {
let session = LanguageModelSession()
let response = try await session.respond(
to: "Tiivistä seuraava teksti yhdellä virkkeellä:\n\n\(text)"
)
return response.content
}
Huomaa kaksi seikkaa. Ensinnäkin LanguageModelSession() ottaa oletuksena SystemLanguageModel.default-mallin, joten et tarvitse erillistä konfiguraatiota perustapauksissa. Toiseksi sessio säilyttää keskusteluhistorian: jos kutsut respond(to:) samalle sessiolle uudestaan, edellinen prompt ja vastaus ovat osa kontekstia. Tämä on harvoin haluttua eräajossa, joten luo uusi sessio per pyyntö, ellet rakenna varsinaista chat-näkymää.
Voit myös antaa konstruktorille instructions-parametrin, joka toimii kuten muiden LLM-rajapintojen system-viesti. Se annetaan kerran, ja malli kantaa sitä mukanaan koko session ajan:
let session = LanguageModelSession(
instructions: """
Olet kohtelias asiakaspalvelu-assistentti.
Vastaa aina suomeksi ja korkeintaan kahdella virkkeellä.
"""
)
Strukturoitu tuotos @Generable-makrolla
Tämä on kehyksen mielenkiintoisin osa ja syy, miksi en henkilökohtaisesti enää kirjoita käsin JSON-jäsentäjiä LLM-vastauksille. @Generable-makro liittää omaan Swift-tyyppiisi mallin tarvitseman skeeman, ja kun pyydät vastausta tyyppiparametrin kanssa, saat takaisin tyypitetyn arvon.
import FoundationModels
@Generable
struct Recipe {
@Guide(description: "Reseptin nimi suomeksi")
let name: String
@Guide(description: "Valmistusaika minuutteina", .range(5...240))
let minutes: Int
@Guide(description: "Ainesosat järjestyksessä")
let ingredients: [String]
let steps: [String]
}
func recipe(for query: String) async throws -> Recipe {
let session = LanguageModelSession()
let response = try await session.respond(
to: "Ehdota resepti hakusanalle: \(query)",
generating: Recipe.self
)
return response.content
}
Makro generoi taustalla mallin ymmärtämän skeeman, joka pakottaa decoodausvaiheessa tuotoksen vastaamaan tyypin rakennetta. @Guide-attribuutilla annat kentälle kuvauksen ja valinnaisia rajoitteita, esimerkiksi .range, .count tai .enumeration. Tämä on samaa filosofiaa kuin SwiftDatan @Attribute-makroilla, joista kirjoitin SwiftData-oppaassa. Swift-makroista on tullut Applen ensisijainen tapa liimata tyyppisysteemiä ajonaikaiseen käyttäytymiseen.
Sisäkkäiset tyypit toimivat odotetusti, kunhan jokainen taso on merkitty @Generableiksi. enum-arvot ovat myös tuettuja, ja malli osaa valita oikean tapauksen kuvausten perusteella. Optionaaliset kentät tulkitaan niin, että malli voi jättää ne pois, jos kontekstista ei löydy arvoa. Tämä on usein parempi kuin pakottaa malli hallusinoimaan kenttiä.
Streaming-vastaukset reaaliajassa
Käyttöliittymässä on harvoin järkevää odottaa täyttä vastausta ennen näyttämistä. Foundation Models tukee streamingia respond(to:)-metodin streamResponse-variantilla, joka palauttaa AsyncSequencen osittaisista vastauksista.
import SwiftUI
import FoundationModels
@Observable
final class ChatViewModel {
var partial: String = ""
private let session = LanguageModelSession()
func ask(_ prompt: String) async {
partial = ""
do {
let stream = session.streamResponse(to: prompt)
for try await chunk in stream {
partial = chunk.content
}
} catch {
partial = "Virhe: \(error.localizedDescription)"
}
}
}
Tärkeä yksityiskohta: chunk.content on koko kumulatiivinen vastaus tähän mennessä, ei pelkkä uusi pala. Tämä eroaa esimerkiksi OpenAI:n streaming-API:sta, jossa saat deltoja. Applen valinta on käytännöllinen, koska SwiftUI-näkymässä voit sitoa partial-merkkijonon suoraan Text-elementtiin ilman ylimääräistä konkatenointia.
Strukturoidulla tuotoksella streamaus toimii streamResponse(to:generating:)-variantilla ja palauttaa osittaisia, valinnaisia kenttiä sisältäviä arvoja. Tämä on hyödyllistä esimerkiksi silloin, kun haluat näyttää reseptin nimen heti, vaikka vaiheet ovat vielä kesken.
Työkalujen kutsuminen Tool-protokollalla
Yksi kehyksen aliarvioiduimmista ominaisuuksista on natiivi työkalukutsutuki. Toteutat Tool-protokollan, rekisteröit sen sessioon, ja malli päättää automaattisesti, milloin kutsua sitä. Kaikki Swiftissä, ilman erillistä funktiokuvausten JSON-skeemaa.
import FoundationModels
import CoreLocation
struct WeatherTool: Tool {
let name = "currentWeather"
let description = "Hakee säätiedot annetulle paikkakunnalle."
@Generable
struct Arguments {
@Guide(description: "Kaupungin nimi suomeksi")
let city: String
}
func call(arguments: Arguments) async throws -> ToolOutput {
let temperature = try await WeatherService.shared.celsius(for: arguments.city)
return ToolOutput("\(arguments.city): \(temperature) °C")
}
}
let session = LanguageModelSession(tools: [WeatherTool()])
let response = try await session.respond(
to: "Mitä mun pitää pukea Helsingissä tänään?"
)
Malli näkee promptin, tunnistaa tarvitsevansa säätiedon, kutsuu WeatherToolia city: "Helsinki"-argumentilla, saa tuloksen takaisin ja muotoilee vastauksen sen pohjalta. Voit rekisteröidä useita työkaluja samaan sessioon, ja malli valitsee tarvittavat itse. Tämän rakentaminen pilvi-LLM:llä vaatisi tyypillisesti oman funktiokutsuvälikerroksen, joten Applen ratkaisu säästää huomattavasti liimakoodia.
Pidä työkalut nopeina ja idempotentteina. Malli voi kutsua samaa työkalua useita kertoja saman vastauksen aikana, jos prompt sitä vihjaa, ja jos työkalu tekee verkkopyyntöjä, käyttäjä huomaa viiveen heti.
Saatavuuden tarkistus ja virheenkäsittely
Sovelluksesi käynnistyy aina laitteilla, joilla Foundation Models ei ole saatavilla. Tarkista tilanne ennen istunnon luontia ja näytä sopiva käyttöliittymä:
import FoundationModels
enum FoundationModelsState {
case ready
case needsAppleIntelligence
case downloadingModel
case unsupportedDevice
case other(String)
}
func currentState() -> FoundationModelsState {
switch SystemLanguageModel.default.availability {
case .available:
return .ready
case .unavailable(.appleIntelligenceNotEnabled):
return .needsAppleIntelligence
case .unavailable(.modelNotReady):
return .downloadingModel
case .unavailable(.deviceNotEligible):
return .unsupportedDevice
case .unavailable(let reason):
return .other(String(describing: reason))
}
}
Tähän modelNotReady-tilaan törmää erityisesti laitteen ensimmäisellä käynnistyskerralla iOS 26 -päivityksen jälkeen. Malli latautuu taustalla, ja saatavuus muuttuu itsestään muutaman minuutin kuluessa. Hyvä käyttäjäkokemus näyttää tämän tilan ja tarjoaa pull-to-refresh-tyyppisen tavan tarkistaa uudelleen. Älä polla saatavuutta sekunneittain, koska se on energiasyöppö.
Itse istuntopyynnöt voivat heittää LanguageModelSession.GenerationError-tyyppisiä virheitä, joista yleisimmät ovat .guardrailViolation (sisältösuodattimet estivät vastauksen), .exceededContextWindow (prompt + historia ylittävät kontekstin) ja .cancelled (kutsuja perui Tehtävän). Käsittele ainakin nämä kolme erikseen, koska yleinen "jokin meni pieleen" -viesti ei auta käyttäjää.
Foundation Models vs. Core ML vs. pilvi-LLM
Foundation Models ei ole kaikkien ongelmien ratkaisu. Tässä yhteenveto, milloin valita mitäkin:
Ominaisuus
Foundation Models
Core ML
Pilvi-LLM (esim. Claude)
Verkkoyhteys
Ei tarvita
Ei tarvita
Pakollinen
Mallin koko
~3 mrd parametria
Vapaa, sovelluksen mukana
100+ mrd parametria
Tehtävät
Teksti, työkalut
Yleinen ML (kuva, ääni, teksti)
Mikä tahansa teksti
Strukturoitu tuotos
@Generable, sisäänrakennettu
Manuaalinen
Vaihtelee tarjoajan mukaan
Yksityisyys
Täysin laitteessa
Täysin laitteessa
Tiedot lähtevät palvelimelle
Kustannukset
Ilmainen
Ilmainen
Tokeniperustainen lasku
Laiterajoitteet
Apple Intelligence -laitteet
Kaikki Apple-laitteet
Ei rajoitteita
Käytännössä Foundation Models on oikea valinta, kun kyseessä on lyhyt tekstin muokkaus, luokittelu, yhteenveto tai työkalupohjainen aktio paikallisilla tiedoilla. Pilvi-LLM voittaa, kun tarvitset pitkän kontekstin (100k+ tokenia), korkeampaa päättelykykyä tai monimutkaisten suomalaisten lakitekstien analyysiä. Core ML on yhä paras valinta omilla, kapeisilla malleilla, esimerkiksi kuvanluokittelu, tai jos sovelluksesi pitää toimia myös iPhone 12:lla.
Yksityisyys, suorituskyky ja akkukulutus
Kaikki Foundation Models -pyynnöt suoritetaan laitteessa. Tämä ei ole vain markkinointiväite vaan rajapinnan suunnitteluperiaate: kehys ei sisällä tapaa pyytää pilviversiota mallista. Applen Apple Foundation Models -tekninen raportti kannattaa lukea, jos haluat ymmärtää, miten Private Cloud Compute eroaa tästä rajapinnasta. Se on eri kerros, johon sovelluskehittäjillä ei ole suoraa pääsyä.
Suorituskykynäkökulmasta odota noin 30–60 tokenia sekunnissa iPhone 16 Prossa, hieman vähemmän iPhone 15 Prossa, ja noin 100 tokenia sekunnissa M4 Macissa. Tämä riittää sujuvaan streamattuun tekstigenerointiin, mutta ei reaaliaikaiseen puheeseen. Akkukulutus on huomattava: pitkä 1000 tokenin generointi vastaa karkeasti 30 sekunnin videontoistoa. Älä siis aja mallia taustalla jatkuvasti.
Jos sovelluksesi käyttöliittymä rakentuu uuden Liquid Glass -suunnittelukielen päälle, varaa generoinnin ajaksi selkeä latausindikaattori. Käyttäjät ovat tottuneet pilvi-LLM:ien latenssiin, mutta on-device-mallin lämpenemisviive ensimmäisellä pyynnöllä voi tuntua erikoiselta.
Usein kysytyt kysymykset
Voinko käyttää Foundation Models -kehystä ilman internetiä?
Kyllä. Koko inferenssi tapahtuu laitteessa, eikä kehys lähetä yhtään tavua verkkoon. Ainoa verkkoa vaativa vaihe on mallin alkulataus, joka tapahtuu kerran iOS 26 -päivityksen yhteydessä järjestelmätasolla.
Miten päivitän olemassa olevan Core ML -projektin Foundation Modelsiin?
Et kirjaimellisesti päivitä, sillä kyseessä ovat eri kehykset eri käyttötarkoituksiin. Jos Core ML -mallisi tekee tekstigenerointia tai luokittelua yleisellä kielimallilla, voit korvata sen Foundation Models -istunnolla. Jos malli on oma erikoistunut luokittelija, pidä se Core ML:ssä, koska Foundation Models on yleismalli eikä korvaa erikoismalleja.
Voiko Foundation Models -mallia hienosäätää omalla datalla?
Suoraa fine-tuning-rajapintaa ei kehittäjille ole, mutta Apple tukee LoRA-adaptereita rajoitetuilla yrityskumppanuusohjelmilla. Useimmissa tapauksissa instructions-parametri ja muutaman esimerkin few-shot-prompting riittävät. Yhden hengen sivuprojekteissa et tarvitse fine-tuningia.
Mikä on Foundation Models -mallin kontekstin enimmäispituus?
Konteksti-ikkuna on 4096 tokenia (prompt + ohjeet + tuotos yhteensä) Xcode 26.0 -beetan aikaan. Tämä on huomattavasti pienempi kuin pilvi-LLM:issä, joten älä syötä mallille kokonaisia PDF-dokumentteja. Käytä esikäsittelyä, pilkkomista tai yhteenvetokierroksia.
Tukeeko Foundation Models suomen kieltä?
Kyllä, mutta laatu on parhainta englanniksi. Suomen ja muiden Pohjoismaiden kielten tuki lisättiin iOS 26.1:ssä, ja se riittää hyvin yhteenvetoihin, luokitteluun ja yksinkertaiseen generointiin. Monimutkaisemmissa luovissa tehtävissä huomaat eron, ja siinä tilanteessa harkitse pilvi-LLM:ää.
Opi rakentamaan Live Activities -toimintoja ja Dynamic Island -käyttöliittymiä iOS 26:lle ActivityKitin ja SwiftUI:n avulla. Sisältää APNs-integraation, koodiesimerkit ja parhaat käytännöt vuodelle 2026.