Avatar ·

Какой аналог NSLocalizedString в Swift для локализации строк?

Всем привет! Я только начал изучать Swift и пытаюсь добавить локализацию в своё приложение. В Objective-C я видел, что используется макрос `NSLocalizedString`, но в Swift, насколько я понимаю, макросов нет. Я пробовал использовать `NSLocalizedString("key", comment: "comment")` напрямую в Swift, и это работает, но мне кажется, что это не совсем правильно. Есть ли в Swift какой-то встроенный аналог, который более идиоматичен для этого языка? Например, что-то вроде `LocalizedString("key")` или другой синтаксис? Вот пример моего текущего кода: ```swift let welcomeMessage = NSLocalizedString("welcome_message", comment: "Приветственное сообщение на главном экране") ``` Меня смущает, что приходится писать `comment:` каждый раз. Можно ли как-то упростить? Или это нормальная практика в Swift? Также я слышал про `String(localized:)` в новых версиях iOS, но не уверен, когда это появилось и как правильно использовать. Буду благодарен за примеры кода и совет, как лучше организовать локализацию в Swift-проекте. Заранее спасибо! <<>>

Основное решение: используем NSLocalizedString в Swift

В Swift нет отдельного макроса, и использование NSLocalizedString — это абсолютно нормальная и рекомендуемая практика. Однако современный Swift предлагает более удобные способы.

Базовый вариант, который вы уже используете, корректен:

let welcomeMessage = NSLocalizedString("welcome_message", comment: "Приветствие на главном экране")

Параметр comment: обязателен, но его можно опустить, если использовать расширение:

extension String {
    static func localized(_ key: String) -> String {
        return NSLocalizedString(key, comment: "")
    }
}

// Использование:
let welcomeMessage = String.localized("welcome_message")

Современный подход: String(localized:) (iOS 15+, macOS 12+)

Начиная с iOS 15, Apple представила новый инициализатор String(localized:), который работает напрямую с LocalizedStringResource. Это самый идиоматичный способ в новых проектах:

let welcomeMessage = String(localized: "welcome_message")
// или с комментарием:
let welcomeMessage = String(localized: "welcome_message", comment: "Приветствие")

Преимущества:

  • Не нужно импортировать Foundation (работает с SwiftUI)
  • Поддержка интерполяции строк с плюрализацией
  • Более строгая типизация

Продвинутый вариант: использование LocalizedStringKey

В SwiftUI можно использовать LocalizedStringKey для автоматической локализации:

Text(LocalizedStringKey("welcome_message"))
// или просто:
Text("welcome_message") // SwiftUI автоматически ищет локализацию

Лучшая практика для больших проектов

Создайте отдельный файл с константами локализации:

enum LocalizedStrings {
    static let welcome = String(localized: "welcome_message")
    static let logout = String(localized: "logout_button")
    static let error = String(localized: "error_title")
}

// Использование:
label.text = LocalizedStrings.welcome

Или используйте структуру с computed properties:

struct Localization {
    static var welcome: String {
        return NSLocalizedString("welcome_message", comment: "")
    }
}

Работа с плюрализацией и аргументами

Для строк с подстановками и множественными числами используйте String.localizedStringWithFormat:

let count = 5
let formatString = NSLocalizedString("items_count", comment: "Количество элементов")
let result = String.localizedStringWithFormat(formatString, count)
// В Localizable.strings: "items_count" = "У вас %d элементов";

Для iOS 15+ проще:

let result = String(localized: "items_count \(count)") 
// В строковом каталоге (xcstrings) укажите плейсхолдер

Резюме: Для старых проектов используйте NSLocalizedString с расширением. Для новых проектов (iOS 15+) переходите на String(localized:) и LocalizedStringKey в SwiftUI. Главное — избегайте хардкода строк и используйте ключи в Localizable.strings или .xcstrings.

<<>>

Альтернативный подход: использование CocoaPods/SPM библиотек

Если вам не хватает стандартных средств, можно использовать сторонние библиотеки, которые упрощают локализацию. Например, популярная библиотека R.swift генерирует типизированные доступы к строкам:

// После настройки R.swift
let welcomeMessage = R.string.localizable.welcomeMessage()

Преимущества:

  • Автодополнение в Xcode
  • Ошибки на этапе компиляции, если ключ не существует
  • Поддержка аргументов и плюрализации

Недостатки:

  • Дополнительная зависимость
  • Необходимость перегенерации файлов при изменении строк

Другой вариант — SwiftGen, который также генерирует Swift-код из ваших файлов локализации. Обе библиотеки хорошо документированы и поддерживаются.

Однако для большинства проектов стандартного NSLocalizedString или String(localized:) более чем достаточно. Сторонние решения стоит рассматривать только если у вас очень много строк и вы хотите избежать ошибок с ключами.