← 모든 글

Apple Translation 프레임워크: 무료, 온디바이스, 그리고 생각보다 정교한 도구

Apple의 Translation 프레임워크는 텍스트를 기기 안에서 무료로 번역합니다. API 키도 필요 없고, 언어가 한 번 설치되고 나면 네트워크 호출도 일어나지 않습니다1. Core ML 모델 위에 만들어졌고 시스템에 기본 탑재되어 있어서, 앱은 Translate 앱이 쓰는 것과 똑같은 번역 엔진을 그대로 쓸 수 있습니다. 예전 같으면 클라우드 번역 비용과 개인정보 문제를 함께 떠안아야 했던 다국어 기능이, 이번에도 비용상 0에 수렴하는 셈입니다. 그리고 Foundation Models 프레임워크6가 그랬듯, 흥미로운 대목은 잘 풀리는 경로가 아닙니다. 데모가 슬쩍 건너뛰는 가장자리, 그러니까 첫 번역을 가로막는 언어 다운로드, 아무 설명 없이 동작을 거부하는 시뮬레이터, 그리고 도입 방식 자체를 규정해 버리는 SwiftUI 전용 인터페이스가 진짜 볼 만한 부분입니다.

핵심 요약

  • 인터페이스는 둘, 요구 iOS 버전도 둘입니다. translationPresentation은 Apple이 기본 제공하는 번역 팝오버를 띄웁니다(iOS 17.4+). TranslationSessiontranslationTask 수정자를 통해 접근하며, 직접 만든 UI 안에서 프로그래밍 방식으로 번역합니다(iOS 18+)2.
  • 프로그래밍 방식 번역은 async입니다. translationTask 클로저 안에서 TranslationSession을 넘겨받고, 이를 호출해 문자열 하나 또는 여러 건을 한꺼번에 번역합니다3.
  • 일괄 번역이 정식 기능입니다. 하나씩 반복문을 돌며 기다리는 대신, 목록 전체를 한 번의 요청으로 번역하면서 각 결과를 원래 입력과 짝지어 유지할 수 있습니다3.
  • 번역 UI는 SwiftUI 전용이고, iOS 시뮬레이터에서는 아예 동작하지 않습니다. 둘 다 모르고 부딪히기 딱 좋은 지점이니, 설계와 테스트를 여기에 맞춰 잡아야 합니다4.
  • 오프라인이라는 말은 먼저 다운로드가 있다는 뜻입니다. 특정 언어 쌍의 첫 번역에서 언어 번들을 내려받는데, 이건 세부 사항이 아니라 직접 처리해야 할 실제 UX 순간입니다5.
  • 알아 둘 만한 조합은 이렇습니다. 사용자 입력을 Translation으로 번역한 뒤 Foundation Models로 추론하면, 단일 언어로 짠 온디바이스 에이전트 기능이 기기가 설치할 수 있는 모든 언어에서 작동합니다.

두 가지 인터페이스: 시스템 팝오버와 내 UI

이 프레임워크는 서로 뚜렷이 구분되는 두 가지 번역 방식을 제공하며, 어느 쪽을 고르느냐가 사실상 의사결정의 대부분입니다.

가볍게 얹는 쪽은 iOS 17.4부터 쓸 수 있는 translationPresentation입니다. 뷰에 붙이고 isPresented 플래그를 바인딩한 다음 텍스트를 넘기면, 플래그가 true로 바뀌는 순간 시스템이 콘텐츠 위로 자체 번역 팝오버를 밀어 올립니다2:

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

번역 로직은 한 줄도 작성하지 않고, 결과도 볼 수 없습니다. UI와 상호작용은 Apple이 전부 가져갑니다. “사용자가 이 문단을 번역하게 해 준다” 정도가 목적이라면 이것으로 기능이 끝나며, 더 무거운 수단을 꺼내 드는 건 헛수고입니다.

프로그래밍 방식 인터페이스는 iOS 18부터 제공되는 TranslationSession이고, translationTask 수정자를 통해 접근합니다. 이 수정자는 비동기 클로저를 실행하면서 직접 호출할 수 있는 세션을 건네주므로, 번역된 텍스트가 내 코드로 돌아오고 표시 방식도 내가 정합니다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. 사고의 틀은 이렇습니다. 언어 쌍의 첫 번역은 일회성 에셋 다운로드로 취급하세요. 실제로 그것이기 때문입니다. 다운로드가 존재한다는 전제 위에서 UX를 설계하면 무료 오프라인 번역이라는 이점이 제대로 살아나고, 무시하면 그 이점은 멈춤 현상 뒤로 숨어 버립니다.

늦게 알면 반나절을 날리는 사실이 두 가지 더 있습니다. 번역 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으로 감싸면 기기가 설치할 수 있는 모든 언어에서 작동하게 만들 수 있습니다. 세션은 하나의 언어 쌍에 대해 구성되므로, 두 방향에는 각각의 세션 구성이 필요합니다(사용자 언어에서 영어로, 그다음 영어에서 사용자 언어로). 두 계층 모두 기기 안에서 돌고 모두 무료이며 어떤 것도 휴대폰을 떠나지 않습니다. 그래서 다국어 버전이라고 해서 단일 언어 버전이 치르지 않던 개인정보 대가나 클라우드 비용을 새로 물지 않습니다. 이 구성(들여오며 번역, 추론, 내보내며 번역)이야말로 작은 온디바이스 기능을 진짜 전 세계용으로 만들어 주는 패턴이며, 양쪽 절반이 모두 로컬에서 무료로 돌기 때문에 비로소 가능한 이야기입니다.

쓰지 말아야 할 때

온디바이스 번역은 무료이고 사적이라, 앱 내 번역의 기본값으로 삼기에 적절합니다. 다만 솔직히 맞지 않는 경우도 몇 가지 있습니다.

  • 최고 수준의 번역 품질이나 가장 넓은 언어 지원이 필요한 경우. 온디바이스 모델은 훌륭하지만 최고는 아니고, 설치 가능한 언어 집합도 유한합니다. 위험 부담이 큰 번역(법률, 의료, 출판 콘텐츠)이라면 전용 클라우드 번역 서비스가 여전히 품질과 범위에서 앞섭니다.
  • 첫 사용 시 다운로드를 감당할 수 없는 경우. 네트워크 없이 첫 실행에서 즉시 작동해야 하는 기능이라면, 온보딩 중에 미리 내려받지 않는 한 다운로드 요구 사항만으로도 온디바이스 번역이 탈락할 수 있습니다.
  • 앱이 UIKit 기반이고 SwiftUI 호스트를 끼워 넣을 여지가 없거나, 흐름이 시뮬레이터에서 돌아야 하는 경우(예: 자동화된 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 구성이 각각 필요합니다(사용자 언어에서 영어로, 그다음 영어에서 사용자 언어로). 두 계층 모두 기기 안에서 무료로 돌기 때문에, 다국어 버전이라고 해서 개인정보 대가나 클라우드 비용이 추가로 들지 않습니다.

온디바이스 번역을 쓰지 말아야 할 때는 언제인가요?

가능한 최고 품질이나 가장 넓은 언어 지원이 필요할 때(법률, 의료, 출판 콘텐츠), 네트워크 없이 첫 실행에서 즉시 작동해야 하는데 미리 다운로드해 둘 수 없을 때, 또는 흐름이 시뮬레이터에서 돌아야 하거나 앱이 UIKit 기반이라 SwiftUI 호스트를 끼워 넣을 여지가 없을 때입니다. 마지막 제약들은 타협 가능한 권고가 아니라 명확한 한계입니다.



  1. Apple Developer, “Translation” framework. Core ML 모델을 기반으로 시스템이 제공하는 온디바이스 번역용 퍼스트파티 프레임워크로, 언어 에셋이 설치되고 나면 네트워크 호출 없이 로컬에서 번역을 수행합니다. 

  2. Apple Developer, “translationPresentation(isPresented:text:attachmentAnchor:arrowEdge:replacementAction:)”(iOS 17.4+)는 뷰 위에 시스템 기본 번역 UI를 표시합니다. “translationTask(_:action:)”(iOS 18+)는 비동기 클로저를 실행하면서, 직접 만든 인터페이스에서 프로그래밍 방식 번역에 쓸 TranslationSession을 제공합니다. 

  3. Apple Developer, TranslationSessionTranslationSession.Request. translate(_:)는 문자열 하나를 처리하고, 일괄 처리용 API는 요청 배열을 받습니다. 각 요청에는 clientIdentifier가 담겨 있어 짝이 맞는 응답에 그대로 돌아오므로, 순서와 무관하게 결과를 원래 입력과 다시 연결할 수 있습니다. 

  4. Translation 프레임워크의 번역 API는 SwiftUI 뷰 수정자(translationTask, translationPresentation)를 통해 노출되며 UIKit 진입점이 없습니다. UIKit 화면에서는 (예: UIHostingController를 통해) SwiftUI 뷰를 품어야 사용할 수 있습니다. 또한 이 프레임워크는 실제 기기를 요구하며 iOS 시뮬레이터에서는 동작하지 않습니다. Translation 프레임워크 문서“Translating text within your app”을 참고하세요. 

  5. Apple Developer, “Translating text within your app”LanguageAvailability. 원본-대상 언어 쌍의 첫 번역에서 필요한 언어 에셋을 내려받습니다. 프레임워크는 언어 사용 가능 여부 확인 수단과 언어 쌍을 미리 준비(다운로드)하는 방법을 제공하므로, 앱은 첫 사용에서 멈춰 서는 대신 다운로드 시점을 직접 관리할 수 있습니다. 

  6. 온디바이스 역량을 조합하는 방법에 대한 저자의 관련 분석: Apple Foundation Models: 온디바이스 LLM 프레임워크, Apple Foundation Models로 만드는 온디바이스 LLM, Writing Tools API 도입기. 들여오며 번역, 추론, 내보내며 번역 패턴은 단일 언어로 작성한 Foundation Models 호출을 Translation으로 감싸, 기기를 벗어나지 않고도 온디바이스 기능을 다국어로 만들어 줍니다. 

관련 게시물

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

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

6 분 소요

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

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

7 분 소요

Claude Code Auto Mode Is Not a Security Boundary

Anthropic closed a working auto-mode bypass as Informative: the classifier is best-effort, not a guarantee. What actuall…

10 분 소요