skills/apple-foundation-models/references/localization.md

15 KiB

Localization

Overview

The on-device system language model is multilingual, which means the same model understands and generates text in any language that Apple Intelligence supports. The model supports using different languages for:

  • Prompts
  • Instructions
  • The output that the model produces

When you enhance your app with multilingual support, generate content in the language people prefer by:

  1. Prompting the model with the language you prefer
  2. Including the target language for your app in the instructions you provide the model
  3. Determining the language or languages a person wants to use when they interact with your app
  4. Gracefully handling languages that Apple Intelligence doesn't support

For more information about the languages and locales that Apple Intelligence supports, see the "Supported languages" section in How to get Apple Intelligence.

Prompt the Model in the Language You Prefer

Write your app's built-in prompts in the language with which you normally write code, if Apple Intelligence supports that language. Translate your prompts into a supported language if your preferred language isn't supported.

Important: In the code below, all inputs need to be in supported language for the model to understand, including all Generable types and descriptions:

@Generable(description: "Basic profile information about a cat")
struct CatProfile {
    var name: String

    @Guide(description: "The age of the cat", .range(0...20))
    var age: Int

    @Guide(description: "One sentence about this cat's personality")
    var profile: String
}

#Playground {
    let response = try await LanguageModelSession().respond(
        to: "Generate a rescue cat",
        generating: CatProfile.self
    )
}

Because the framework treats Generable types as model inputs, the names of properties like age or profile are just as important as the @Guide descriptions for helping the model understand your request.

Check a Person's Language Settings for Your App

People can use the Settings app on their device to configure the language they prefer to use on a per-app basis, which might differ from their default language.

If your app supports a language that Apple Intelligence doesn't, you need to verify that the current language setting of your app is supported before you call the model.

Keep in mind: Language support improves over time in newer model and OS versions. Thus, someone using your app with an older OS may not have the latest language support.

Using supportsLocale(_:)

Before you call the model, run supportsLocale(_:) to verify the support for a locale. By default, the method uses current, which takes into account a person's current language and app-specific settings.

This method returns true if the model supports this locale, or if this locale is considered similar enough to a supported locale (e.g., en-AU and en-NZ):

if SystemLanguageModel.default.supportsLocale() {
    // Language is supported.
}

For advanced use cases where you need full language support details, use supportedLanguages to retrieve a list of languages supported by the on-device model.

Handle Unsupported Language or Locale Errors

When you call respond(to:options:) on a LanguageModelSession, the Foundation Models framework checks:

  • The language or languages of the input prompt text
  • Whether your prompt asks the model to respond in any specific language or languages

If the model detects a language it doesn't support, the session throws LanguageModelSession.GenerationError.unsupportedLanguageOrLocale(_:). Handle the error by communicating to the person using your app that a language in their request is unsupported.

If your app supports languages or locales that Apple Intelligence doesn't, help people that use your app by:

  • Explaining that their language isn't supported by Apple Intelligence in your app
  • Disabling your Foundation Models framework feature
  • Providing an alternative app experience, if possible

IMPORTANT: Guardrails for model input and output safety are only for supported languages and locales. If a prompt contains sensitive content in an unsupported language (typically a short phrase mixed-in with text in a supported language), it might not throw an unsupportedLanguageOrLocale error. If unsupported-language detection fails, the guardrails may also fail to flag that short, unsupported content.


Use Instructions to Set the Locale and Language

For locales other than United States English, you can improve response quality by telling the model which locale to use by detailing a set of Instructions.

Start with the exact phrase in English. This special phrase comes from the model's training and reduces the possibility of hallucinations in multilingual situations:

func localeInstructions(for locale: Locale = Locale.current) -> String {
    if Locale.Language(identifier: "en_US").isEquivalent(to: locale.language) {
        // Skip the locale phrase for U.S. English.
        return "" 
    } else {
        // Specify the person's locale with the exact phrase format.
        return "The person's locale is \(locale.identifier)."
    }
}

Explicitly Set the Model Output Language

After you set the locale in Instructions, you may need to explicitly set the model output language.

By default, the model responds in the language or languages of its inputs. If your app supports multiple languages, prompts that you write and inputs from people using your app might be in different languages. For example, if you write your built-in prompts in Spanish, but someone using your app writes inputs in Dutch, the model may respond in either or both languages.

Use Instructions to explicity tell the model which language or languages with which it needs to respond. You can phrase this request in different ways, for example:

  • "You MUST respond in Italian"
  • "You MUST respond in Italian and be mindful of Italian spelling, vocabulary, entities, and other cultural contexts of Italy."

These instructions can be in the language you prefer.

let session = LanguageModelSession(
    instructions: "You MUST respond in U.S. English."
)
let prompt = // A prompt that contains Spanish and Italian.
let response = try await session.respond(to: prompt)

Finally, thoroughly test your instructions to ensure the model is responding in the way you expect. If the model isn't following your instructions, try capitalized words like "MUST" or "ALWAYS" to strengthen your instructions.

Example: Multilingual Conversations

// Session maintains language consistency
let session = LanguageModelSession(
    instructions: Instructions("You are a multilingual assistant. You MUST respond in the same language as the prompt.")
)

// First message in English
let response1 = try await session.respond(
    to: Prompt("Hello, can you help me?")
)

// Switch to Spanish
let response2 = try await session.respond(
    to: Prompt("Ahora responde en español")
)
// Model switches to Spanish

// Back to English
let response3 = try await session.respond(
    to: Prompt("Switch back to English please")
)
// Model switches back to English

Best Practices

1. Check Locale Support

func createLocalizedSession() async throws -> LanguageModelSession {
    let model = SystemLanguageModel(useCase: .general)
    
    // Check if user's locale is supported
    guard model.supportsLocale(Locale.current) else {
        // Fall back to English or show warning
        print("Warning: User's locale not fully supported")
        // You can still use the model, it will do its best
    }
    
    let session = LanguageModelSession(model: model)
    return session
}

2. Provide Language Context

let userLanguage = Locale.current.languageCode ?? "en"

let prompt = Prompt {
    Instructions {
        "Respond in \(Locale.current.localizedString(forLanguageCode: userLanguage) ?? "English")"
        "Use culturally appropriate examples"
    }
    userQuestion
}

3. Handle Mixed Languages

let prompt = Prompt {
    Instructions {
        "You can understand questions in any language"
        "Always respond in the same language as the question"
        "If the question mixes languages, respond in the primary language"
    }
    "What is SwiftUI? ¿Qué es?"
}

4. Regional Variations

// Handle regional language differences
let region = Locale.current.regionCode ?? "US"

let prompt = Prompt {
    Instructions {
        "Use \(region) regional conventions"
        "Use local date formats, measurements, and terminology"
    }
    "When is Thanksgiving?"
}
// US: November, Canada: October

Localization Patterns

Date and Time Formatting

let prompt = Prompt {
    Instructions {
        "Use the user's locale for date formatting"
        "Region: \(Locale.current.identifier)"
    }
    "What's the date format for today?"
}

// US locale: MM/DD/YYYY
// European locale: DD/MM/YYYY

Number Formatting

let prompt = Prompt {
    Instructions("Format numbers according to \(Locale.current.identifier) conventions")
    "What is 1234567.89 formatted for display?"
}

// US: 1,234,567.89
// Europe: 1.234.567,89

Currency

let currencyCode = Locale.current.currencyCode ?? "USD"

let prompt = Prompt {
    Instructions("Use \(currencyCode) when discussing money")
    "How much does a coffee cost?"
}

Example: Multilingual App

class MultilingualAssistant {
    private let model: SystemLanguageModel
    private var session: LanguageModelSession?
    
    init() async throws {
        self.model = SystemLanguageModel(useCase: .general)
        
        // Check locale support
        if !model.supportsLocale(Locale.current) {
            print("Warning: Limited support for current locale")
        }
        
        // Create session with language context
        let languageName = Locale.current.localizedString(
            forLanguageCode: Locale.current.languageCode ?? "en"
        ) ?? "English"
        
        self.session = LanguageModelSession(
            model: model,
            instructions: Instructions {
                "You are a helpful assistant"
                "Respond in \(languageName)"
                "Use appropriate cultural references"
                "Format dates, numbers, and currency according to \(Locale.current.identifier)"
            }
        )
    }
    
    func ask(_ question: String) async throws -> String {
        guard let session = session else {
            throw AssistantError.notInitialized
        }
        
        return try await session.respond(to: Prompt(question))
    }
    
    func switchLanguage(_ locale: Locale) async throws {
        guard model.supportsLocale(locale) else {
            throw AssistantError.localeNotSupported
        }
        
        let languageName = locale.localizedString(
            forLanguageCode: locale.languageCode ?? "en"
        ) ?? "English"
        
        self.session = LanguageModelSession(
            model: model,
            instructions: Instructions {
                "Respond in \(languageName)"
                "Use \(locale.identifier) conventions"
            }
        )
    }
}

enum AssistantError: Error {
    case notInitialized
    case localeNotSupported
}

Language Fallbacks

func getPreferredLanguages() -> [String] {
    // Get user's preferred languages in order
    return Locale.preferredLanguages.compactMap { identifier in
        let locale = Locale(identifier: identifier)
        return locale.languageCode
    }
}

func selectSupportedLanguage(from preferences: [String], model: SystemLanguageModel) -> String? {
    for langCode in preferences {
        let locale = Locale(identifier: langCode)
        if model.supportsLocale(locale) {
            return langCode
        }
    }
    return "en" // Fallback to English
}

// Usage
let model = SystemLanguageModel(useCase: .general)
let preferences = getPreferredLanguages()
let selectedLang = selectSupportedLanguage(from: preferences, model: model)

let prompt = Prompt {
    Instructions("Respond in language code: \(selectedLang ?? "en")")
    userQuestion
}

Testing Localization

class LocalizationTests: XCTestCase {
    func testMultipleLanguages() async throws {
        let model = SystemLanguageModel(useCase: .general)
        
        let languages = [
            ("en", "What is SwiftUI?"),
            ("es", "¿Qué es SwiftUI?"),
            ("fr", "Qu'est-ce que SwiftUI?"),
            ("de", "Was ist SwiftUI?")
        ]
        
        for (langCode, question) in languages {
            let locale = Locale(identifier: langCode)
            
            if model.supportsLocale(locale) {
                let session = LanguageModelSession(model: model)
                let response = try await session.respond(to: Prompt(question))
                
                XCTAssertFalse(response.isEmpty, "Response should not be empty for \(langCode)")
                print("\(langCode): \(response.prefix(50))...")
            } else {
                print("Language \(langCode) not supported, skipping")
            }
        }
    }
}

Common Pitfalls

1. Don't Assume English

// Bad - Assumes English
let prompt = Prompt("Explain...")

// Good - Respects user language
let prompt = Prompt {
    Instructions("Respond in the user's preferred language")
    userQuestion
}

2. Cultural Sensitivity

let prompt = Prompt {
    Instructions {
        "Be culturally sensitive"
        "Avoid idioms that don't translate"
        "Use appropriate examples for \(Locale.current.regionCode ?? "US")"
    }
    userQuestion
}

3. Mixed Content

// Handle code + natural language
let prompt = Prompt {
    Instructions {
        "Explain concepts in \(currentLanguage)"
        "Keep code examples and technical terms in English"
        "Comment code in \(currentLanguage)"
    }
    "Explain this Swift code: \(codeSnippet)"
}

Summary

Key Points:

  1. Automatic Language Detection - Model uses device language by default
  2. Check Support - Use supportsLocale(_:) before assuming support
  3. Explicit Instructions - Request specific languages in prompts
  4. Regional Awareness - Handle date, number, and currency formats
  5. Fallback Strategy - Provide fallback languages for unsupported locales
  6. Cultural Sensitivity - Adapt content to regional norms
  7. Mixed Languages - Handle code examples with multilingual explanations
  8. Test Thoroughly - Verify behavior across different locales

Foundation Models provides robust multilingual support, allowing your app to serve users worldwide in their preferred language.