Что такое эквивалент NSLocalizedString в 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
однако, это очень долго и совсем не удобно.
14 ответов:
Я использую следующее решение:
1) создать расширение:
extension String { var localized: String { return NSLocalizedString(self, tableName: nil, bundle: Bundle.main, value: "", comment: "") } }
2) в локализации.строки file:
"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) в .файл строки:
/* with !!! */ "Hi" = "Привет!!!";
3), используя:
myLabel.text = "Hi".localized(withComment: "with !!!")
The
NSLocalizedString
существует также в мире Swift.func NSLocalizedString( key: String, tableName: String? = default, bundle: NSBundle = default, value: String = default, #comment: String) -> String
The
tableName
,bundle
иvalue
параметры отмечены знакомdefault
ключевое слово, которое означает, что мы можем опустить эти параметры при вызове функции. В этом случае будут использованы значения по умолчанию.это приводит к выводу, что вызов метода можно упростить до:
NSLocalizedString("key", comment: "comment")
используя этот способ, можно создать другую реализацию для разных типов (т. е. Int или пользовательские классы, такие как CurrencyUnit,...). Его также можно сканировать для этого метода вызова с помощью утилиты genstrings. Просто добавьте обычный флаг в команду
genstrings MyCoolApp/Views/SomeView.swift -s localize -o .
вариация существующих ответов:
Swift 4:
extension String { func localized(withComment comment: String? = nil) -> String { return NSLocalizedString(self, comment: comment ?? "") } }
затем вы можете просто использовать его с или без комментария:
"Goodbye".localized() "Hello".localized(withComment: "Simple greeting")
Пожалуйста, обратите внимание, что
genstrings
не работать с этим решением.
создал небольшой вспомогательный метод для случаев, когда" комментарий " всегда игнорируется. Меньше кода легче читать:
public func NSLocalizedString(key: String) -> String { return NSLocalizedString(key, comment: "") }
просто поместите его в любом месте (вне класса) и Xcode найдете этот глобальный метод.
Swift 3 версия :)...
import Foundation extension String { var localized: String { return NSLocalizedString(self, tableName: nil, bundle: Bundle.main, value: "", comment: "") } }
наверное, самый лучший способ это здесь.
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 по-прежнему будет работать
- вы можете добавьте больше расширений, например, по одному на контроллер вида, чтобы все было аккуратно
на самом деле, вы можете использовать два этапа для перевода ваших текстов в проектах Swift:
1) на первом этапе используется старый способ создания всех ваших переводимых строк:
NSLocalisedString("Text to translate", comment: "Comment to comment")
1.1), то вы должны использовать genstrings для создания локализации.строки:
$ genstrings *swift
2) После этого, вы должны использовать это ответ.
2.1) используйте опцию XCode "найти и заменить" на основе регулярного выражения. Что касается данного примера (если вы без комментариев) регулярное выражение будет:
NSLocalizedString\((.*)\, comment:\ \"\"\)
и заменить
.localized
или (если у вас есть замечания)
NSLocalizedString\((.*)\, comment:\ (.*)\)
и заменить
.localizedWithComment(comment: )
вы можете играть с регулярным выражением и различными комбинациями расширений, как вы хотите. Общий способ заключается в разделении всего процесса на две фазы. Надеюсь, это поможет.
при разработке SDK. Тебе нужна дополнительная операция.
1) создать локализации.строки как обычно в YourLocalizeDemoSDK.
2) создать то же самое локализации.строки в YourLocalizeDemo.
3) найти Bundle Path из YourLocalizeDemoSDK.
Swift4:
// if you use NSLocalizeString in NSObject, you can use it like this let value = NSLocalizedString("key", tableName: nil, bundle: Bundle(for: type(of: self)), value: "", comment: "")
Bundle(for: type(of: self))
поможет вам найти пакет в YourLocalizeDemoSDK. Если вы используетеBundle.main
вместо этого вы получите неверное значение(на самом деле это будет та же строка с ключом).но если вы хотите использовать расширение строки, упомянутые доктор ОКС. Тебе нужно сделать еще кое-что. Расширение origin выглядит следующим образом.
extension String { var localized: String { return NSLocalizedString(self, tableName: nil, bundle: Bundle.main, value: "", comment: "") } }
как мы знаем, мы разрабатываем SDK,
Bundle.main
получит пучок yourlocalizedemo's bundle. Это не то, чего мы хотим. Нам нужен пакет в YourLocalizeDemoSDK. Это трюк, чтобы найти его быстро.запустите приведенный ниже код в экземпляре NSObject в YourLocalizeDemoSDK. И вы получите URL-адрес YourLocalizeDemoSDK.
let bundleURLOfSDK = Bundle(for: type(of: self)).bundleURL let mainBundleURL = Bundle.main.bundleURL
распечатайте оба url-адреса, вы обнаружите, что мы можем построить базу bundleURLofSDK на mainBundleURL. В этом случае, это будет:
let bundle = Bundle(url: Bundle.main.bundleURL.appendingPathComponent("Frameworks").appendingPathComponent("YourLocalizeDemoSDK.framework")) ?? Bundle.main
и расширение строки будет:
extension String { var localized: String { let bundle = Bundle(url: Bundle.main.bundleURL.appendingPathComponent("Frameworks").appendingPathComponent("YourLocalizeDemoSDK.framework")) ?? Bundle.main return NSLocalizedString(self, tableName: nil, bundle: bundle, value: "", comment: "") } }
надеюсь, что это помогает.
Я создал свой собственный genstrings своего рода инструмент для извлечения строк с помощью пользовательской функции перевода
extension String { func localizedWith(comment:String) -> String { return NSLocalizedString(self, tableName: nil, bundle: Bundle.main, value: "", comment: comment) } }
https://gist.github.com/Maxdw/e9e89af731ae6c6b8d85f5fa60ba848c
он проанализирует все ваши swift-файлы и экспортирует строки и комментарии в вашем коде в a .строки файла.
наверное, не самый простой способ сделать это, но это возможно.
хотя это не отвечает на проблему сокращения, но это помогло мне организовать сообщения, я создал структуру для сообщений об ошибках, как показано ниже
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 работы.
и это команда genstrings используется
find ./ -name \*.swift -print0 | xargs -0 genstrings -o .en.lproj
полезно для использования в модульных тестах:
Это простая версия, которая может быть расширена на различные случаи использования (например, с использованием табличных имен).
public func NSLocalizedString(key: String, referenceClass: AnyClass, comment: String = "") -> String { let bundle = NSBundle(forClass: referenceClass) return NSLocalizedString(key, tableName:nil, bundle: bundle, comment: comment) }
используйте его так:
NSLocalizedString("YOUR-KEY", referenceClass: self)
или такой комментарий:
NSLocalizedString("YOUR-KEY", referenceClass: self, comment: "usage description")
локализация с языком по умолчанию:
extension String { func localized() -> String { let defaultLanguage = "en" let path = Bundle.main.path(forResource: defaultLanguage, ofType: "lproj") let bundle = Bundle(path: path!) return NSLocalizedString(self, tableName: nil, bundle: bundle!, value: "", comment: "") } }
когда вы переводите, скажем, с английского, где фраза одна и та же, на другой язык, где она отличается (из-за Пола, спряжения глаголов или склонения) простой форма NSString в Swift, которая работает во всех случаях, является одним из трех аргументов. Например, английская фраза "previous was", по-разному переводится на русский для случая" weight "("предыдущий был") и для "талии" ("предыдущая была").
в этом случае вам нужно два разных перевода для одного источника (с точки зрения инструмента XLIFF, рекомендованного в WWDC 2018). Вы не можете достичь этого с помощью двух аргументов NSLocalizedString, где " предыдущий был "будет одинаковым как для" ключа", так и для английского перевода (т. е. для значения). Единственный способ-использовать три аргумента формы
NSLocalizedString("previousWasFeminine", value: "previous was", comment: "previousWasFeminine") NSLocalizedString("previousWasMasculine", value: "previous was", comment: "previousWasMasculine")
где ключи ("previousWasFeminine "и" previousWasMasculine") различны.
I знайте, что общий совет заключается в переводе фразы в целом, однако, иногда это слишком трудоемко и неудобно.