Что такое NSLocalizedString эквивалент в Swift?

184

Существует ли Swift эквивалент NSLocalizedString(...)? В Objective-C мы обычно используем:

NSString *string = NSLocalizedString(@"key", @"comment");

Как я могу добиться того же в Swift? Я нашел функцию:

func NSLocalizedString(
    key: String,
    tableName: String? = default,
    bundle: NSBundle = default,
    value: String = default,
    #comment: String) -> String

Однако он очень длинный и совсем не удобный.

  • 2
    Лучше всего создать более короткую версию фрагмента кода: NSLocalizedString ("", comment: "") ... Мне понравилось решение расширения, но проблема в том, что genstrings не будут захватывать эти строки в файл перевода.
  • 2
    В Swift 3 вы можете просто использовать NSLocalizedString("Cancel", comment: "Cancel button title") , используя значения по умолчанию. Это удобно, я думаю.
Показать ещё 1 комментарий
Теги:
localization
nslocalizedstring

11 ответов

233
Лучший ответ

NSLocalizedString существует также в мире Swift.

func NSLocalizedString(
    key: String,
    tableName: String? = default,
    bundle: NSBundle = default,
    value: String = default,
    #comment: String) -> String

Параметры tableName, bundle и value отмечены ключевым словом default, что означает, что мы можем опустить эти параметры при вызове функции. В этом случае будут использоваться значения по умолчанию.

Это приводит к выводу, что вызов метода можно упростить до:

NSLocalizedString("key", comment: "comment")
  • 41
    Разница лишь в том, что комментарий не может быть нулевым, а автозаполнение далеко не интуитивно понятно для короткой версии.
  • 1
    это больше не работает, я получаю сообщение об ошибке, говорящее, что недостаточно аргументов.
Показать ещё 3 комментария
316

Я использую следующее решение:

1) создать расширение:

extension String {
    var localized: String {
        return NSLocalizedString(self, tableName: nil, bundle: Bundle.main, value: "", comment: "")
    }
}

2) в файле Localizable.strings:

"Hi" = "Привет";

3) пример использования:

myLabel.text = "Hi".localized

наслаждайтесь!;)

- UPD: -

для случая с комментариями вы можете использовать это решение:

1) Расширение:

extension String {
    func localized(withComment:String) -> String {
        return NSLocalizedString(self, tableName: nil, bundle: Bundle.main, value: "", comment: withComment)
    }
}

2) в файле .strings:

/* with !!! */
"Hi" = "Привет!!!";

3), используя:

myLabel.text = "Hi".localized(withComment: "with !!!")
  • 0
    @drOX Возможно, вы захотите отредактировать код так, чтобы он return NSLocalizedString(self, comment: self)
  • 79
    Единственная проблема заключается в том, что вы не сможете использовать утилиту genstrings для генерации ваших файлов .strings.
Показать ещё 16 комментариев
9

Создал небольшой вспомогательный метод для случаев, где "комментарий" всегда игнорируется. Меньше кода легче читать:

public func NSLocalizedString(key: String) -> String {
    return NSLocalizedString(key, comment: "")
}

Просто поместите его в любом месте (вне класса), и Xcode найдет этот глобальный метод.

  • 11
    Это плохая практика. Комментарии рекомендуются и полезны, если вы не делаете весь перевод самостоятельно.
  • 0
    Даже если вы переводите сами, комментарии будут полезны, особенно в большом проекте.
9

Используя этот способ, можно создать различную реализацию для разных типов (т.е. Int или пользовательских классов, таких как CurrencyUnit,...). Его также можно сканировать для этого метода, используя утилиту genstrings. Просто добавьте флаг подпрограммы в команду

genstrings MyCoolApp/Views/SomeView.swift -s localize -o .
Расширение

:

import UIKit

extension String {
    public static func localize(key: String, comment: String) -> String {
        return NSLocalizedString(key, comment: comment)
    }
}

использование:

String.localize("foo.bar", comment: "Foo Bar Comment :)")
6

версия Swift 3:)...

import Foundation

extension String {
    var localized: String {
        return NSLocalizedString(self, tableName: nil, bundle: Bundle.main, value: "", comment: "")
    }
}
4

На самом деле вы можете использовать две фазы для перевода ваших текстов в проекты Swift:

1) На первом этапе используется старый способ создания всех ваших переводимых строк:

NSLocalisedString("Text to translate", comment: "Comment to comment")

1.1) Затем вы должны использовать genstrings для генерации Localizable.strings:

$ genstrings *swift

2) Затем вы должны использовать этот ответ.

2.1) Используйте опцию "Найти и заменить" XCode на основе регулярного выражения. Что касается данного примера (если у вас нет комментариев), регулярное выражение будет выглядеть следующим образом:

NSLocalizedString\((.*)\, comment:\ \"\"\) 

и замените его на

$1.localized

или (если у вас есть комментарии)

NSLocalizedString\((.*)\, comment:\ (.*)\)

и замените его на

$1.localizedWithComment(comment: $2)

Вы можете свободно играть с регулярным выражением и различными комбинациями расширений по своему усмотрению. Общий путь - разделение всего процесса на две фазы. Надеюсь, что это поможет.

  • 0
    Извините, я не понимаю смысла многих ответов здесь. В чем преимущество метода перед использованием NSLocalizedString("Cancel", comment: "Cancel button title") ?
  • 1
    @LShi некоторые люди жаловались, что NSLocalizedString выглядит менее стремительно, чем должно выглядеть. String.localized с другой стороны, выглядит более Swifty, но вы не можете использовать утилиту gesntrings которая обычно используется для облегчения вашей работы с интернационализацией. Я хочу сказать, что оба подхода довольно легко смешать. Так что в основном это вопрос читабельности.
3

Вероятно, лучший способ - это здесь.

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

и

import Foundation
extension String {
    static let Hello = NSLocalizedString("Hello")
    static let ThisApplicationIsCreated = NSLocalizedString("This application is created by the swifting.io team")
    static let OpsNoFeature = NSLocalizedString("Ops! It looks like this feature haven't been implemented yet :(!")
}

вы можете использовать его так:

let message: String = .ThisApplicationIsCreated
print(message)

для меня это лучшее, потому что

  • Жестко закодированные строки находятся в одном конкретном файле, поэтому в день, когда вы хотите изменить его, это действительно легко.
  • Легче использовать, чем вручную набирать строки в вашем файле каждый раз
  • genstrings будет работать
  • вы можете добавить дополнительные расширения, например, один для каждого контроллера просмотра, чтобы поддерживать чистоту
  • 2
    Следует отметить, что строки, определенные описанным способом, являются статическими. Приложение должно быть перезапущено после смены языка в приложении «Настройки iOS». Если нет, перезапустите его самостоятельно, чтобы увидеть изменения. Это также может привести к перегрузке памяти, поскольку мы инициализируем все строки сразу, а не в тот момент, когда они нужны.
  • 2
    Я думаю, что лучше использовать вычисляемые свойства здесь, как это static var Hello: String = { return NSLocalizedString("Hello") }
1

Полезно для использования в модульных тестах:

Это простая версия, которая может быть распространена на различные варианты использования (например, с использованием табличных имен).

public func NSLocalizedString(key: String, referenceClass:AnyClass) -> String 
{
    let bundle = NSBundle(forClass: referenceClass)
    return NSLocalizedString(key, tableName:nil, bundle: bundle, comment: "")
}

Используйте его следующим образом:

NSLocalizedString("YOUR-KEY", referenceClass: self)
  • 1
    Это плохая практика, чтобы оставить комментарии.
  • 0
    @ Хосе Спасибо за ваш комментарий. Код был задуман как идея, а не как шаблон для копирования и вставки. Но я добавил возможность добавлять комментарии, если хотите;)
0

Хотя это не отвечает на проблему сокращения, но это помогло мне организовать сообщения, я создал структуру сообщений об ошибках, например ниже

struct Constants {
    // Error Messages
    struct ErrorMessages {
        static let unKnownError = NSLocalizedString("Unknown Error", comment: "Unknown Error Occured")
        static let downloadError = NSLocalizedString("Error in Download", comment: "Error in Download")
    }
}

let error = Constants.ErrorMessages.unKnownError

Таким образом, вы можете организовать сообщения и заставить генерации работать.

И это используется команда genstrings

find ./ -name \*.swift -print0 | xargs -0 genstrings -o .en.lproj
0

Я создал свой собственный метод генерации сортировки для извлечения строк с использованием специальной функции перевода

extension String {

    func localizedWith(comment:String) -> String {
        return NSLocalizedString(self, tableName: nil, bundle: Bundle.main, value: "", comment: comment)
    }

}

https://gist.github.com/Maxdw/e9e89af731ae6c6b8d85f5fa60ba848c

Он будет анализировать все ваши быстрые файлы и экспортировать строки и комментарии в ваш код в файл .strings.

Вероятно, это не самый простой способ сделать это, но это возможно.

  • 0
    Макс, мне нравится быстрый код, который ты написал для генерации строк. Это впечатляет. Ура!
0

Когда у меня есть один источник, но несколько целей (переводы), например, для разных грамматических полов, которые я использую (Swift 3)

NSLocalizedString("previousWasFeminine", value: "previous was", comment: "previousWasFeminine")

NSLocalizedString("previousWasMasculine", value: "previous was", comment: "previousWasMasculine")

Ещё вопросы

Сообщество Overcoder
Наверх
Меню