Framework Translation od Apple: darmowy, na urządzeniu i sprytniejszy, niż się wydaje
Framework Translation od Apple tłumaczy tekst lokalnie na urządzeniu, bezpłatnie, bez klucza API i bez zapytania sieciowego, gdy dany język jest już zainstalowany1. Opiera się na modelach Core ML, jest częścią systemu i daje aplikacji dokładnie ten sam silnik tłumaczenia, z którego korzysta systemowa aplikacja Translate. W przypadku funkcji wielojęzycznych, które kiedyś oznaczały rachunek za tłumaczenie w chmurze i pytanie o prywatność, koszt znów zaokrągla się do zera. Podobnie jak przy frameworku Foundation Models6, najciekawsze nie jest to, co działa od razu, lecz przypadki brzegowe pomijane w demonstracjach: pobieranie języka, które blokuje pierwsze tłumaczenie, symulator, który po cichu odmawia współpracy, oraz dostępność wyłącznie w SwiftUI, która kształtuje sposób wdrożenia.
TL;DR
- Dwa interfejsy, dwie wersje iOS.
translationPresentationwyświetla wbudowane w system okienko tłumaczenia (iOS 17.4+).TranslationSession, dostępna przez modyfikatortranslationTask, pozwala tłumaczyć z poziomu kodu we własnym UI (iOS 18+)2. - Tłumaczenie z poziomu kodu jest
async. Wewnątrz domknięciatranslationTaskotrzymuje się obiektTranslationSession; wywołuje się go, aby przetłumaczyć pojedynczy ciąg znaków lub całą partię3. - Tryb wsadowy to pełnoprawna ścieżka. Listę tłumaczy się jednym żądaniem, zachowując powiązanie każdego wyniku z jego danymi wejściowymi, zamiast iterować i czekać na każde tłumaczenie po kolei3.
- Interfejs tłumaczenia istnieje wyłącznie w SwiftUI i nie działa w symulatorze iOS. Obie rzeczy łatwo odkryć boleśnie, po fakcie — warto projektować i testować z tym na uwadze4.
- Tryb offline zaczyna się od pobierania. Pierwsze tłumaczenie dla danej pary językowej pobiera pakiety językowe — to realny moment w UX, który trzeba obsłużyć, a nie drobiazg5.
- Połączenie warte zapamiętania: tekst użytkownika tłumaczy się za pomocą Translation, a następnie analizuje przy użyciu Foundation Models — i jednojęzyczna funkcja agenta działająca na urządzeniu obsługuje każdy język, jaki da się na nim zainstalować.
Dwa interfejsy: systemowe okienko i własny UI
Framework oferuje dwa odrębne sposoby tłumaczenia, a wybór właściwego stanowi zasadniczą część decyzji.
Lżejszym podejściem jest translationPresentation, dostępne od iOS 17.4. Dołącza się je do widoku, wiąże z flagą isPresented i przekazuje tekst; gdy flaga przyjmie wartość true, system wysuwa nad treścią własne okienko tłumaczenia2:
.translationPresentation(isPresented: $showTranslation, text: selectedText)
Nie pisze się przy tym żadnej logiki tłumaczenia i nie widzi się wyniku — UI oraz interakcja należą do Apple. Dla scenariusza „pozwól użytkownikowi przetłumaczyć ten fragment” to cała funkcja, a sięganie po cokolwiek cięższego to zmarnowana praca.
Ścieżką sterowaną kodem jest TranslationSession, dostępna od iOS 18, a prowadzi do niej modyfikator translationTask. Modyfikator uruchamia asynchroniczne domknięcie i przekazuje sesję, którą wywołuje się samodzielnie — przetłumaczony tekst wraca więc do kodu i można go wyrenderować po swojemu2:
.translationTask(configuration) { session in
let response = try await session.translate("Good morning")
await MainActor.run { translated = response.targetText }
}
Podział jest klarowny. translationPresentation służy pokazaniu użytkownikowi tłumaczenia w interfejsie Apple. TranslationSession służy wprowadzeniu przetłumaczonego tekstu do własnych danych i widoków. Większość aplikacji, które robią coś więcej niż jednorazowe „przetłumacz to”, sięga po sesję.
Tłumaczenie wsadowe: tłumaczy się listę, nie pętlę
Szczegółem, który odróżnia płynną funkcję od siermiężnej, jest przetwarzanie wsadowe. Gdy trzeba przetłumaczyć listę (wiadomości z czatu, wpisy katalogu, zestaw etykiet), nie należy iterować i czekać (await) na każde tłumaczenie po kolei. TranslationSession przyjmuje partię żądań i zwraca odpowiedzi — każdą dopasowaną do swojego żądania — w jednym przebiegu3:
.translationTask(configuration) { session in
let requests = items.map { TranslationSession.Request(sourceText: $0.text, clientIdentifier: $0.id) }
for try await response in session.translate(batch: requests) {
store[response.clientIdentifier] = response.targetText
}
}
Kluczowy jest clientIdentifier: wraca on w odpowiedzi, dzięki czemu każde tłumaczenie da się przypisać do właściwego wiersza bez polegania na kolejności. Tryb wsadowy pozwala też frameworkowi rozplanować pracę wydajnie, zamiast ponosić narzut przy każdym wywołaniu w pętli. Dla czegokolwiek większego niż pojedynczy ciąg znaków — tryb wsadowy.
Rzeczywistość trybu offline, której nikt nie pokazuje na zrzutach ekranu
Oto przypadek brzegowy, który zamienia czystą demonstrację w zgłoszenie do wsparcia. Tłumaczenie działa na urządzeniu, ale język musi się najpierw na tym urządzeniu znaleźć. Przy pierwszym tłumaczeniu danej pary źródło–cel system pobiera pakiety językowe, a pobieranie wymaga czasu i połączenia sieciowego5. Jeśli uruchomi się tłumaczenie i wyrenderuje wynik bez obsługi pobierania, funkcja przy pierwszym użyciu każdego nowego języka sprawia wrażenie zawieszonej.
Warto obsłużyć to świadomie. Framework pozwala sprawdzić dostępność języka i przygotować (pobrać) parę z wyprzedzeniem, zanim będzie potrzebna — można więc pokazać stan „przygotowuję tłumaczenie” albo pobrać dane w spokojniejszym momencie, zamiast blokować się w środku interakcji5. Model myślowy: pierwsze tłumaczenie pary językowej to jednorazowe pobranie zasobów, bo dokładnie tym jest. Gdy UX uwzględnia istnienie pobierania, korzyść z darmowego trybu offline naprawdę wybrzmiewa; gdy się je zignoruje, korzyść znika za zawieszonym interfejsem.
Dwa fakty, które kosztują całe popołudnie, jeśli pozna się je za późno. Interfejsy tłumaczenia to modyfikatory SwiftUI, więc ekran napisany w UIKit sięga po nie, osadzając widok SwiftUI (przez UIHostingController) — choć TranslationSession da się też skonstruować bezpośrednio, do pracy bez UI4. Ponadto framework nie działa w symulatorze iOS ani iPadOS; tłumaczenie testuje się na fizycznym urządzeniu4. Żadna z tych rzeczy nie jest wyraźnie udokumentowana, a o obie łatwo się potknąć.
Tłumaczenie w parze z Foundation Models
Wniosek wart zapamiętania łączy ten framework z resztą stosu działającego na urządzeniu. Większość lokalnej pracy z językiem zakłada, że dane wejściowe są w języku, który logika aplikacji i model systemowy obsługują dobrze. Prawdziwi użytkownicy nie współpracują. Framework Translation zamyka tę lukę: tekst użytkownika tłumaczy się na język, w którym funkcja prowadzi rozumowanie, na przetłumaczonym tekście uruchamia się pracę Foundation Models, a wynik tłumaczy się z powrotem.
Kształt przypomina klamrę: tłumaczenie na wejściu, rozumowanie, tłumaczenie na wyjściu.
// 1. translate the user's text into English (session configured for their language -> en)
let english = try await inboundSession.translate(userText).targetText
// 2. reason on-device, monolingually, in English
let summary = try await LanguageModelSession()
.respond(to: "Summarize in one line: \(english)").content
// 3. translate the result back (a session configured for en -> their language)
let localized = try await outboundSession.translate(summary).targetText
Funkcja segregująca zgłoszenia do wsparcia, funkcja podsumowująca notatki, funkcja wydobywająca intencje — każdą z nich można napisać raz, jednojęzycznie, i sprawić, że zadziała w dowolnym języku możliwym do zainstalowania na urządzeniu, obejmując wywołanie Foundation Models klamrą z Translation. Oba kierunki wymagają dwóch konfiguracji sesji (z języka użytkownika na angielski, potem z angielskiego z powrotem), ponieważ jedna sesja obsługuje jedną parę językową. Obie warstwy działają na urządzeniu, obie są bezpłatne i nic nie opuszcza telefonu, więc wersja wielojęzyczna nie kosztuje ani prywatności, ani rachunku za chmurę, których nie kosztowała wersja jednojęzyczna. To złożenie — tłumaczenie na wejściu, rozumowanie, tłumaczenie na wyjściu — jest wzorcem, który czyni niewielką lokalną funkcję naprawdę globalną, a możliwe jest wyłącznie dlatego, że obie połowy działają lokalnie i za darmo.
Kiedy z niego nie korzystać
Tłumaczenie na urządzeniu jest darmowe i prywatne, co czyni je właściwym domyślnym wyborem dla tłumaczenia wewnątrz aplikacji. W kilku przypadkach jest jednak — mówiąc uczciwie — narzędziem niewłaściwym.
- Potrzebna jest najwyższa możliwa jakość tłumaczenia albo najszersze pokrycie językowe. Modele działające na urządzeniu są dobre, lecz nie najlepsze z dostępnych, a zbiór instalowalnych języków jest skończony. Przy tłumaczeniach, w których stawka jest wysoka (prawo, medycyna, treści publikowane), dedykowana chmurowa usługa tłumaczeniowa wciąż wygrywa jakością i zasięgiem.
- Pobieranie przy pierwszym użyciu jest nie do zaakceptowania. Jeśli funkcja musi zadziałać natychmiast przy pierwszym uruchomieniu i bez sieci, sam wymóg pobrania może przekreślić tłumaczenie na urządzeniu — chyba że dane pobierze się wcześniej, podczas onboardingu.
- Aplikacja jest napisana w UIKit bez miejsca na osadzenie widoku SwiftUI albo przepływ musi działać w symulatorze (na przykład automatyczny test UI). Ograniczenia „tylko SwiftUI” i „nie w symulatorze” to twarde granice, a nie zalecenia.
Framework należy do cichszych zwycięstw w zestawie narzędzi działających lokalnie: to naprawdę darmowy, prywatny silnik tłumaczenia, który większość aplikacji mogłaby wdrożyć w jedno popołudnie. Potrzebna jest tu ta sama umiejętność, którą nagradza reszta tego stosu. Trzeba wiedzieć, który interfejs pasuje (systemowe okienko czy własna sesja), przetwarzać wsadowo, gdy w grę wchodzi lista, i projektować z myślą o pobieraniu, zamiast udawać, że go nie ma. Wtedy tłumaczenie przestaje być zależnością od chmury, a staje się lokalną zdolnością, którą można łączyć ze wszystkim innym, co urządzenie robi za darmo.
FAQ
Czy framework Translation od Apple jest darmowy i działa na urządzeniu?
Tak. Tłumaczenie odbywa się na urządzeniu i jest bezpłatne, a nic nie opuszcza telefonu — dlatego stanowi właściwy domyślny wybór dla tłumaczenia wewnątrz aplikacji. Kompromis polega na tym, że jakość tłumaczenia i pokrycie językowe są dobre, lecz nie najlepsze w klasie, więc zadania o dużej wadze mogą nadal wymagać usługi chmurowej.
Dlaczego pierwsze tłumaczenie się zawiesza albo wymaga pobrania danych?
Tłumaczenie działa na urządzeniu, ale para językowa musi się najpierw na nim znaleźć. Przy pierwszym tłumaczeniu danej pary źródło–cel system pobiera pakiety językowe, co wymaga czasu i połączenia sieciowego5. Warto sprawdzić dostępność i przygotować (pobrać z wyprzedzeniem) parę, zanim będzie potrzebna, aby pokazać stan „przygotowywanie” zamiast blokować się w środku interakcji.
Jakie są dwa sposoby dodania tłumaczenia do aplikacji?
Systemowe okienko przez modyfikator prezentacji SwiftUI albo własny interfejs sterowany przez TranslationSession skonstruowaną bezpośrednio, do pracy bez UI4. Ponieważ oba interfejsy to modyfikatory SwiftUI, ekran w UIKit sięga po nie, osadzając widok SwiftUI za pomocą UIHostingController.
Czy framework Translation od Apple działa w symulatorze?
Nie. Framework nie działa w symulatorze iOS ani iPadOS, więc tłumaczenie testuje się na fizycznym urządzeniu4. To ograniczenie jest twarde, a nie doradcze, i wyklucza również tłumaczenie w automatycznych testach UI uruchamianych w symulatorze.
Jak sprawić, by funkcja oparta na Foundation Models działała w dowolnym języku?
Trzeba objąć ją klamrą: tekst użytkownika przetłumaczyć na język, w którym rozumuje logika aplikacji, na przetłumaczonym tekście uruchomić pracę Foundation Models, a wynik przetłumaczyć z powrotem. Oba kierunki wymagają dwóch konfiguracji TranslationSession (z języka użytkownika na angielski, potem z angielskiego z powrotem), ponieważ jedna sesja obsługuje jedną parę językową. Obie warstwy działają na urządzeniu i są bezpłatne, więc wersja wielojęzyczna nie kosztuje ani prywatności, ani rachunku za chmurę.
Kiedy nie należy korzystać z tłumaczenia na urządzeniu?
Gdy potrzebna jest najwyższa możliwa jakość albo najszersze pokrycie językowe (prawo, medycyna, treści publikowane); gdy funkcja musi zadziałać natychmiast przy pierwszym uruchomieniu bez sieci, a wcześniejsze pobranie danych nie wchodzi w grę; albo gdy przepływ musi działać w symulatorze bądź aplikacja jest napisana w UIKit bez miejsca na osadzenie widoku SwiftUI. Te ostatnie ograniczenia są twardymi limitami.
-
Apple Developer, framework „Translation”. Własny framework Apple do tłumaczenia na urządzeniu, dostarczany przez system i oparty na modelach Core ML; tłumaczy lokalnie, bez zapytania sieciowego, gdy zasoby językowe są już zainstalowane. ↩
-
Apple Developer, “translationPresentation(isPresented:text:attachmentAnchor:arrowEdge:replacementAction:)” (iOS 17.4+) prezentuje nad widokiem wbudowany systemowy interfejs tłumaczenia; “translationTask(_:action:)” (iOS 18+) uruchamia asynchroniczne domknięcie, które udostępnia
TranslationSessiondo tłumaczenia z poziomu kodu we własnym interfejsie. ↩↩↩ -
Apple Developer,
TranslationSessionorazTranslationSession.Request.translate(_:)obsługuje pojedynczy ciąg znaków; wsadowe API przyjmuje tablicę żądań, z których każde niesieclientIdentifierwracający w odpowiadającej mu odpowiedzi, dzięki czemu wyniki da się ponownie powiązać z danymi wejściowymi niezależnie od kolejności. ↩↩↩ -
Interfejsy API do tłumaczenia we frameworku Translation są udostępniane przez modyfikatory widoku SwiftUI (
translationTask,translationPresentation) i nie mają punktu wejścia w UIKit; ekran w UIKit osadza widok SwiftUI (na przykład przezUIHostingController), aby z nich skorzystać. Framework wymaga ponadto fizycznego urządzenia i nie funkcjonuje w symulatorze iOS. Zobacz dokumentację frameworku Translation oraz “Translating text within your app”. ↩↩↩↩↩ -
Apple Developer, “Translating text within your app” oraz
LanguageAvailability. Pierwsze tłumaczenie pary językowej źródło–cel pobiera wymagane zasoby językowe; framework udostępnia sprawdzanie dostępności języków oraz sposób na wcześniejsze przygotowanie (pobranie) pary, dzięki czemu aplikacje mogą zarządzać momentem pobierania, zamiast blokować się przy pierwszym użyciu. ↩↩↩↩ -
Powiązane analizy autora dotyczące komponowania możliwości działających na urządzeniu: Apple Foundation Models: framework LLM na urządzeniu, Lokalne modele LLM w Apple Foundation Models oraz Wdrożenie API Writing Tools. Wzorzec „tłumaczenie na wejściu, rozumowanie, tłumaczenie na wyjściu” obejmuje jednojęzyczne wywołanie Foundation Models klamrą z Translation, aby uczynić lokalną funkcję wielojęzyczną bez opuszczania urządzenia. ↩