← 모든 글

Apple의 Translation 프레임워크: 무료, 온디바이스, 그리고 생각보다 날카롭다

Apple의 Translation 프레임워크는 텍스트를 온디바이스에서, 무료로, API 키 없이, 그리고 언어가 한 번 설치되고 나면 네트워크 호출 없이 번역합니다1. Core ML 모델 위에 구축되어 시스템과 함께 제공되며, 앱에 Translate 앱이 사용하는 것과 동일한 번역 엔진을 제공합니다. 예전에는 클라우드 번역 비용과 프라이버시 문제를 의미하던 다국어 기능이, 이제 다시 비용이 사실상 0에 수렴합니다. 그리고 Foundation Models 프레임워크와 마찬가지로, 흥미로운 부분은 잘 풀리는 경로가 아니라 데모가 건너뛰는 까다로운 지점들입니다. 첫 번역을 가로막는 언어 다운로드, 아무 설명 없이 동작을 거부하는 시뮬레이터, 그리고 채택 방식을 좌우하는 SwiftUI 전용 표면이 그것입니다.

핵심 요약

  • 표면은 둘, iOS 버전도 둘. translationPresentation은 Apple의 내장 번역 팝오버를 띄웁니다(iOS 17.4 이상). translationTask 모디파이어를 통해 도달하는 TranslationSession은 여러분 자신의 UI 안에서 프로그래밍 방식의 번역을 수행합니다(iOS 18 이상)2.
  • 프로그래밍 방식의 번역은 async입니다. translationTask 클로저 안에서 TranslationSession을 받게 되고, 이를 호출해 문자열 하나를 번역하거나 묶음으로 번역합니다3.
  • 묶음 번역이 일급 시민입니다. 하나씩 반복하며 await하는 대신, 목록 전체를 한 번의 요청으로 번역하면서 각 결과를 입력과 짝지어 유지합니다3.
  • 번역 UI는 SwiftUI 전용이며, iOS 시뮬레이터에서는 동작하지 않습니다. 둘 다 모르고 부딪혀서 어렵게 알게 되기 쉬우니, 그에 맞게 설계하고 테스트하세요4.
  • 오프라인이라는 말은 먼저 다운로드한다는 뜻입니다. 어떤 언어 쌍의 첫 번역은 번들을 내려받는데, 이것은 세부 사항이 아니라 여러분이 직접 다뤄야 할 실제 사용자 경험의 순간입니다5.
  • 알아 둘 만한 조합은 이것입니다. 사용자 입력은 Translation으로 번역하고, 그 결과를 Foundation Models로 추론하면, 단일 언어로 작성된 온디바이스 에이전트 기능이 기기가 설치할 수 있는 모든 언어에서 작동합니다.

두 가지 표면: 시스템 팝오버와 여러분 자신의 UI

이 프레임워크는 번역하는 두 가지 뚜렷한 방법을 제공하며, 올바른 쪽을 고르는 것이 결정의 대부분입니다.

가벼운 쪽은 translationPresentation으로, iOS 17.4부터 사용할 수 있습니다. 뷰에 붙이고, isPresented 플래그를 바인딩하고, 텍스트를 전달합니다. 플래그가 true로 바뀌면 시스템이 여러분의 콘텐츠 위로 자체 번역 팝오버를 밀어 올립니다2.

.translationPresentation(isPresented: $showTranslation, text: selectedText)

번역 로직은 한 줄도 작성하지 않고 결과도 보지 않습니다. UI와 상호작용은 Apple이 소유합니다. “사용자가 이 구절을 번역하게 하자”는 경우라면 이것이 기능 전체이며, 더 무거운 무언가에 손을 뻗는 것은 헛수고입니다.

프로그래밍 방식의 표면은 TranslationSession으로, iOS 18부터 사용할 수 있고 translationTask 모디파이어를 통해 도달합니다. 이 모디파이어는 async 클로저를 실행하고 여러분이 직접 호출하는 세션을 건네주므로, 번역된 텍스트가 여러분의 코드로 돌아오고 여러분 방식대로 렌더링하게 됩니다2.

.translationTask(configuration) { session in
    let response = try await session.translate("Good morning")
    await MainActor.run { translated = response.targetText }
}

구분은 깔끔합니다. translationPresentation은 Apple의 UI로 사용자에게 번역을 보여 주기 위한 것입니다. TranslationSession은 번역된 텍스트를 여러분의 데이터와 뷰로 가져오기 위한 것입니다. 일회성 “이거 번역해” 이상을 하는 대부분의 앱은 세션에 손을 뻗습니다.

묶음 번역: 반복문이 아니라 목록을 번역하라

매끄러운 기능과 덜컹거리는 기능을 가르는 세부 사항은 묶음 처리입니다. 목록(채팅 메시지, 카탈로그 항목, 라벨 한 세트)을 번역해야 한다면, 반복문을 돌며 각 번역을 차례로 await하지 마세요. TranslationSession은 요청 묶음을 받아서, 각 응답을 자신의 요청과 짝지은 채로 한 번에 돌려줍니다3.

.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
    }
}

중요한 부분은 clientIdentifier입니다. 이 값이 응답에 그대로 돌아오므로, 순서에 의존하지 않고도 각 번역을 자신이 속한 행과 짝지을 수 있습니다. 묶음 처리는 또한 프레임워크가 반복문 전반에 걸친 호출당 부담을 치르는 대신 작업을 효율적으로 스케줄링하게 해 줍니다. 문자열 하나를 넘어서는 무엇이든, 묶음으로 처리하세요.

아무도 스크린샷 찍지 않는 오프라인의 현실

깔끔한 데모를 지원 티켓으로 바꾸는 까다로운 지점이 여기 있습니다. 번역은 온디바이스에서 실행되지만, 언어가 먼저 기기에 있어야 합니다. 앱이 주어진 출발-도착 언어 쌍을 처음 번역할 때, 시스템은 언어 번들을 내려받으며, 그 다운로드에는 시간과 네트워크 연결이 필요합니다5. 다운로드를 전혀 처리하지 않은 채 번역을 실행하고 결과를 렌더링하면, 여러분의 기능은 모든 새 언어에 대해 첫 사용 시 멈춰 버린 것처럼 보입니다.

이것을 의도적으로 다루세요. 프레임워크는 언어 가용성을 확인하고 필요한 순간에 앞서 미리 언어 쌍을 준비(다운로드)할 수 있게 해 주므로, 상호작용 도중에 멈추는 대신 “번역 준비 중” 상태를 보여 주거나 좀 더 한가한 순간에 미리 내려받을 수 있습니다5. 사고 모형은 이렇습니다. 언어 쌍의 첫 번역을 일회성 에셋 다운로드처럼 취급하세요. 실제로 그것이 바로 그런 것이기 때문입니다. 다운로드가 존재한다는 전제로 사용자 경험을 설계하면 오프라인이면서 무료라는 이점이 제대로 안착하고, 무시하면 그 이점이 멈춤 뒤로 숨어 버립니다.

뒤늦게 알면 오후 한나절을 날리는 사실이 둘 더 있습니다. 번역 UI 표면들은 SwiftUI 모디파이어이므로, UIKit 화면은 이들에 도달하기 위해 (UIHostingController를 통해) SwiftUI 뷰를 호스팅합니다. 다만 UI가 없는 작업이라면 TranslationSession을 직접 생성할 수도 있습니다4. 그리고 이 프레임워크는 iOS나 iPadOS 시뮬레이터에서 동작하지 않습니다. 번역은 실제 기기에서 테스트하세요4. 둘 다 크게 문서화되어 있지 않고, 둘 다 정면으로 부딪히기 쉽습니다.

번역을 Foundation Models와 짝짓기

새겨 둘 만한 종합은 이 프레임워크를 나머지 온디바이스 스택과 묶습니다. 대부분의 온디바이스 언어 작업은 입력이 여러분의 로직과 시스템 모델이 잘 다루는 언어로 되어 있다고 가정합니다. 실제 사용자는 그렇게 협조하지 않습니다. Translation 프레임워크는 그 간극을 메웁니다. 사용자의 입력을 여러분의 기능이 추론하는 언어로 번역하고, 번역된 텍스트에 대해 Foundation Models 작업을 실행한 다음, 그 결과를 다시 번역해 돌려놓습니다.

그 모양은 괄호입니다. 들어올 때 번역, 추론, 나갈 때 번역.

// 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

지원 분류 기능, 노트 요약기, 의도 추출기. 이들 각각은 단일 언어로 한 번만 작성한 뒤, Foundation Models 호출을 Translation으로 감싸는 것만으로 기기가 설치할 수 있는 모든 언어에서 작동하게 만들 수 있습니다. 세션은 하나의 언어 쌍에 대해 구성되므로, 두 방향은 두 개의 세션 구성을 사용합니다(사용자의 언어에서 영어로, 그다음 영어에서 다시 사용자의 언어로). 두 계층 모두 온디바이스이고, 둘 다 무료이며, 아무것도 기기를 떠나지 않습니다. 그래서 다국어 버전은 단일 언어 버전이 치르지 않던 프라이버시 비용도, 클라우드 청구서도 들지 않습니다. 그 구성(들어올 때 번역, 추론, 나갈 때 번역)이야말로 작은 온디바이스 기능을 진정으로 전 세계적으로 만드는 패턴이며, 두 절반이 모두 로컬에서 무료로 실행되기에 비로소 가능한 일입니다.

언제 쓰지 말아야 하는가

온디바이스 번역은 무료이고 프라이버시를 지켜 주므로, 앱 내 번역의 올바른 기본값입니다. 다만 몇 가지 솔직한 경우에는 잘못된 도구입니다.

  • 가능한 최고의 번역 품질이나 가장 넓은 언어 범위가 필요한 경우. 온디바이스 모델은 좋지만 최고 수준은 아니며, 설치 가능한 언어 집합도 유한합니다. 위험이 큰 번역(법률, 의료, 출판 콘텐츠)이라면 전용 클라우드 번역 서비스가 여전히 품질과 폭에서 앞섭니다.
  • 첫 사용 시 다운로드를 감당할 수 없는 경우. 네트워크 없이 첫 실행에서 즉시 작동해야 하는 기능이라면, 온보딩 중에 미리 내려받지 않는 한 다운로드 요구만으로도 온디바이스 번역이 부적격이 될 수 있습니다.
  • 앱이 SwiftUI 호스트를 둘 여지가 없는 UIKit이거나, 흐름이 시뮬레이터에서 실행되어야 하는 경우(예를 들어 자동화된 UI 테스트). SwiftUI 전용이라는 제약과 시뮬레이터 불가라는 제약은 권고가 아니라 단단한 한계입니다.

이 프레임워크는 온디바이스 도구 모음에서 조용한 승리 중 하나입니다. 대부분의 앱이 오후 한나절이면 채택할 수 있는, 진정으로 무료이고 프라이버시를 지키는 번역 엔진입니다. 필요한 기술은 이 스택의 나머지가 보상하는 것과 똑같습니다. 어떤 표면이 맞는지 알고(시스템 팝오버인지 여러분 자신의 세션인지), 목록이 있으면 묶음으로 처리하고, 다운로드가 없는 척하는 대신 다운로드를 전제로 설계하세요. 그렇게 하면 번역은 클라우드 의존성이기를 그치고, 기기가 무료로 해 주는 다른 모든 것과 함께 조합해 쓰는 로컬 역량이 됩니다.

자주 묻는 질문

Apple의 Translation 프레임워크는 무료이고 온디바이스인가요?

그렇습니다. 번역은 온디바이스에서 실행되고 무료이며, 아무것도 기기를 떠나지 않습니다. 그래서 앱 내 번역의 올바른 기본값이 됩니다. 대신, 번역 품질과 언어 범위가 최고 수준이라기보다 좋은 수준이라는 절충이 따르므로, 위험이 큰 작업이라면 여전히 클라우드 서비스가 필요할 수 있습니다.

왜 첫 번역이 멈추거나 다운로드가 필요한가요?

번역은 온디바이스에서 실행되지만, 언어 쌍이 먼저 기기에 있어야 합니다. 주어진 출발-도착 쌍을 처음 번역할 때, 시스템은 언어 번들을 내려받으며 여기에는 시간과 네트워크 연결이 필요합니다5. 가용성을 확인하고 필요한 순간에 앞서 언어 쌍을 미리 준비(사전 다운로드)해 두면, 상호작용 도중에 멈추는 대신 “준비 중” 상태를 보여 줄 수 있습니다.

앱에 번역을 추가하는 두 가지 방법은 무엇인가요?

SwiftUI 프레젠테이션 모디파이어를 통한 시스템 팝오버, 또는 UI 없는 작업을 위해 직접 생성한 TranslationSession이 구동하는 여러분 자신의 UI입니다4. 표면들이 SwiftUI 모디파이어이기 때문에, UIKit 화면은 UIHostingController를 통해 SwiftUI 뷰를 호스팅하여 이들에 도달합니다.

Apple의 Translation 프레임워크는 시뮬레이터에서 작동하나요?

아니요. 이 프레임워크는 iOS나 iPadOS 시뮬레이터에서 동작하지 않으므로, 번역은 실제 기기에서 테스트해야 합니다4. 이 제약은 권고가 아니라 단단한 한계이며, 자동화된 시뮬레이터 UI 테스트 안에서의 번역도 배제합니다.

Foundation Models 기능을 모든 언어에서 작동하게 하려면 어떻게 하나요?

괄호로 감싸세요. 사용자의 입력을 여러분의 로직이 추론하는 언어로 번역하고, 번역된 텍스트에 대해 Foundation Models 작업을 실행한 다음, 그 결과를 다시 번역해 돌려놓습니다. 세션은 하나의 언어 쌍에 대해 구성되므로, 두 방향은 두 개의 TranslationSession 구성을 사용합니다(사용자의 언어에서 영어로, 그다음 영어에서 다시 사용자의 언어로). 두 계층 모두 온디바이스이고 무료이므로, 다국어 버전은 프라이버시 비용도 클라우드 청구서도 들지 않습니다.

온디바이스 번역을 언제 쓰지 말아야 하나요?

가능한 최고의 품질이나 가장 넓은 언어 범위가 필요할 때(법률, 의료, 출판 콘텐츠), 기능이 네트워크 없이 첫 실행에서 즉시 작동해야 하는데 미리 내려받을 수 없을 때, 또는 흐름이 시뮬레이터에서 실행되어야 하거나 SwiftUI 호스트를 둘 여지가 없는 UIKit일 때입니다. 마지막 제약들은 단단한 한계입니다.



  1. Apple Developer, “Translation” framework. A first-party framework for on-device, system-provided translation built on Core ML models, performing translation locally without a network call once language assets are installed. 

  2. Apple Developer, “translationPresentation(isPresented:text:attachmentAnchor:arrowEdge:replacementAction:)” (iOS 17.4+) presents the system’s built-in translation UI over a view; “translationTask(_:action:)” (iOS 18+) runs an async closure that provides a TranslationSession for programmatic translation in your own interface. 

  3. Apple Developer, TranslationSession and TranslationSession.Request. translate(_:) handles a single string; the batch API takes an array of requests, each carrying a clientIdentifier that returns on the matching response so results can be reassociated with their inputs independent of order. 

  4. The Translation framework’s translation APIs are surfaced through SwiftUI view modifiers (translationTask, translationPresentation) and have no UIKit entry point; a UIKit screen hosts a SwiftUI view (for example via UIHostingController) to use them. The framework also requires a physical device and does not function in the iOS Simulator. See the Translation framework documentation and “Translating text within your app”

  5. Apple Developer, “Translating text within your app” and LanguageAvailability. The first translation of a source-to-target language pair downloads the required language assets; the framework exposes language-availability checks and a way to prepare (download) a pair in advance so apps can manage the download moment rather than stall on first use. 

  6. Author’s related analysis on composing on-device capabilities: Apple Foundation Models: The On-Device LLM Framework, On-Device LLMs with Apple’s Foundation Models, and Writing Tools API adoption. The translate-in, reason, translate-out pattern brackets a monolingual Foundation Models call with Translation to make an on-device feature multilingual without leaving the device. 

관련 게시물

Image Playground API: SwiftUI 시트, 프로그래밍 방식 이미지 생성, 그리고 스타일 제어

Image Playground는 앱에 두 가지 경로를 제공합니다. SwiftUI imagePlaygroundSheet 모디파이어와, 개념으로부터 이미지를 생성하는 프로그래밍 방식의 ImageCreator API입니다…

7 분 소요

Genmoji와 NSAdaptiveImageGlyph: iOS 18+에서의 인라인 이모지

Genmoji는 속성 텍스트에서 NSAdaptiveImageGlyph로 제공됩니다. TextKit 2를 사용하는 UITextView 앱은 supportsAdaptiveImageGlyph를 활성화하고 직렬화를 처리합니…

6 분 소요

The Robots Are Taking Exams in My Search Console

First-party GSC data: 91% of 3.8M impressions fail a human-query filter. Exam questions, pasted errors, and agent sweeps…

10 분 소요