Что такое эквивалент 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) в локализации.струны:
"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) in .файл строк:
/* with !!! */
"Hi" = "Привет!!!";
3), используя:
myLabel.text = "Hi".localized(withComment: "with !!!")
на 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")
используя этот способ, можно создать другую реализацию для разных типов (например, Int или пользовательские классы, такие как CurrencyUnit,...). Его также можно сканировать для этого метода вызова с помощью утилиты genstrings. Просто добавьте флаг routine в команду
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. Это не то, чего мы хотим. Нам нужен пакет в 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 знаю, что общий совет, перевести фразу в целом, однако, иногда это слишком трудоемко и неудобно.