Существует ли 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
Однако он очень длинный и совсем не удобный.
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")
Я использую следующее решение:
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 !!!")
return NSLocalizedString(self, comment: self)
genstrings
для генерации ваших файлов .strings.
Создал небольшой вспомогательный метод для случаев, где "комментарий" всегда игнорируется. Меньше кода легче читать:
public func NSLocalizedString(key: String) -> String {
return NSLocalizedString(key, comment: "")
}
Просто поместите его в любом месте (вне класса), и Xcode найдет этот глобальный метод.
Используя этот способ, можно создать различную реализацию для разных типов (т.е. 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 :)")
версия Swift 3:)...
import Foundation
extension String {
var localized: String {
return NSLocalizedString(self, tableName: nil, bundle: Bundle.main, value: "", comment: "")
}
}
На самом деле вы можете использовать две фазы для перевода ваших текстов в проекты 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)
Вы можете свободно играть с регулярным выражением и различными комбинациями расширений по своему усмотрению. Общий путь - разделение всего процесса на две фазы. Надеюсь, что это поможет.
NSLocalizedString("Cancel", comment: "Cancel button title")
?
NSLocalizedString
выглядит менее стремительно, чем должно выглядеть. String.localized
с другой стороны, выглядит более Swifty, но вы не можете использовать утилиту gesntrings
которая обычно используется для облегчения вашей работы с интернационализацией. Я хочу сказать, что оба подхода довольно легко смешать. Так что в основном это вопрос читабельности.
Вероятно, лучший способ - это здесь.
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)
для меня это лучшее, потому что
static var Hello: String = { return NSLocalizedString("Hello") }
Полезно для использования в модульных тестах:
Это простая версия, которая может быть распространена на различные варианты использования (например, с использованием табличных имен).
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)
Хотя это не отвечает на проблему сокращения, но это помогло мне организовать сообщения, я создал структуру сообщений об ошибках, например ниже
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
Я создал свой собственный метод генерации сортировки для извлечения строк с использованием специальной функции перевода
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.
Вероятно, это не самый простой способ сделать это, но это возможно.
Когда у меня есть один источник, но несколько целей (переводы), например, для разных грамматических полов, которые я использую (Swift 3)
NSLocalizedString("previousWasFeminine", value: "previous was", comment: "previousWasFeminine")
NSLocalizedString("previousWasMasculine", value: "previous was", comment: "previousWasMasculine")
NSLocalizedString("Cancel", comment: "Cancel button title")
, используя значения по умолчанию. Это удобно, я думаю.