Apple представила в iOS 26 технологию, которая может кардинально изменить подход к локализации приложений. Language Discovery - это не просто очередное API, а фундаментальный сдвиг в том, как системы понимают языковые предпочтения пользователей.
Что было раньше:
До iOS 26 мы работали с примитивным API:
let userLanguages = Locale.preferredLanguages
// ["en-US", "es-MX", "fr-CA"]
Это создавало три основные проблемы:
🔹 Только строковые идентификаторы без контекста.
🔹 Пользователи вручную добавляли языки в настройках.
🔹 Не было понимания реальных языковых привычек.
Что изменилось:
Language Discovery анализирует реальное поведение пользователя:
🔹 На каких языках он печатает в сообщениях и почте.
🔹 Какой контент потребляет (музыка, подкасты, статьи).
🔹 В каких приложениях и на каких языках работает.
Все это происходит локально на устройстве с сохранением приватности.
Новое API:
Новое API Locale.preferredLocales возвращает богатые объекты с полной информацией о локали:
🔹 Язык и регион.
🔹 Систему чисел и валюту.
🔹 Направление письма (RTL/LTR).
🔹 Календарную систему.
Пример:
Вместо алфавитного списка из 100+ языков теперь можно показывать умный выбор:
class SmartLanguagePickerManager: ObservableObject {
@Published var preferredLanguages: [LanguageItem] = []
@Published var otherLanguages: [LanguageItem] = []
// Языки, которые поддерживает наше приложение
private let supportedLocales = [
Locale(identifier: "en-US"),
Locale(identifier: "ru-RU"),
Locale(identifier: "de-DE")
]
func organizeLanguages() {
// Получаем предпочтения пользователя через новый API
let userLocales = Locale.preferredLocales
// Сортируем языки на релевантные и остальные
for locale in supportedLocales {
let item = LanguageItem(locale: locale, isPreferred: isRelevant(locale, userLocales))
if item.isPreferred {
preferredLanguages.append(item)
} else {
otherLanguages.append(item)
}
}
// Сортируем остальные языки по алфавиту
otherLanguages.sort { $0.displayName < $1.displayName }
}
private func isRelevant(_ locale: Locale, _ userLocales: [Locale]) -> Bool {
// Проверяем совпадение с предпочтениями пользователя
for userLocale in userLocales {
// Точное совпадение (en-US и en-US)
if locale.identifier == userLocale.identifier { return true }
// Совпадение по языку (en-US и en-GB)
if locale.language.languageCode == userLocale.language.languageCode { return true }
}
return false
}
}
struct LanguageItem: Identifiable {
let id = UUID()
let locale: Locale
let isPreferred: Bool
// Отображаемое название языка
var displayName: String {
locale.localizedString(forIdentifier: locale.identifier) ?? locale.identifier
}
}
Использование во View:
struct LanguagePickerView: View {
@StateObject private var manager = SmartLanguagePickerManager()
var body: some View {
List {
Section("Рекомендуемые языки") {
ForEach(manager.preferredLanguages) { language in
Text(language.displayName)
}
}
Section("Другие языки") {
ForEach(manager.otherLanguages) { language in
Text(language.displayName)
}
}
}
.onAppear {
manager.organizeLanguages()
}
}
}
Преимущества:
🔹 Автоматическое определение RTL без костылей.
🔹 Правильные форматы чисел и дат для каждой культуры.
🔹 Умное сопоставление локалей (en-US -> en-GB).
🔗 Ссылка на подробную статью
💡 Вывод:
Пришло время пересмотреть подход к локализации. Вместо статических списков: умные системы, которые понимают культурный контекст. Вместо ручных настроек: автоматическое определение предпочтений. Особенно порадовало, что Apple сохранила приватность: все вычисления локальные.
➡️ Подписаться на канал
Мобильный трудоголик