有一个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
但是,它很长并且根本不方便。
我用下一个解决方案:
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 !!!")
我已经创建了自己的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文件,并将代码中的字符串和注释导出到.strings文件中。
可能不是最简单的方法,但它是可能的。
虽然这不能解决缩短问题,但这有助于我组织消息,我创建了一个错误消息的结构,如下所示
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
有助于在单元测试中使用:
这是一个简单的版本,可以扩展到不同的用例(例如使用tableNames)。
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: "")
}
}
当你翻译时,比如说英语,一个短语是相同的,到另一种不同的语言(由于性别,动词变形或变形),Swift中最简单的NSString形式在所有情况下都适用于三个参数一个。例如,对于“weight”(“предыдущийбыл”)和“腰部”(“предыдущаябыла”)的情况,英语短语“previous was”被翻译成俄语。
在这种情况下,您需要为一个Source进行两种不同的转换(根据WWDC 2018中推荐的XLIFF工具)。你不能用两个参数NSLocalizedString来实现它,其中“previous is”对于“key”和英语翻译(即对于值)都是相同的。唯一的方法是使用三个参数形式
NSLocalizedString("previousWasFeminine", value: "previous was", comment: "previousWasFeminine")
NSLocalizedString("previousWasMasculine", value: "previous was", comment: "previousWasMasculine")
其中键(“previous Was Feminine”和“previous WasMasculine”)不同。
我知道一般的建议是将这个短语翻译为整体,但是,有时它太耗费时间和不方便。
NSLocalizedString
也存在于斯威夫特的世界里。
func NSLocalizedString(
key: String,
tableName: String? = default,
bundle: NSBundle = default,
value: String = default,
#comment: String) -> String
tableName
,bundle
和value
参数用default
关键字标记,这意味着我们可以在调用函数时省略这些参数。在这种情况下,将使用它们的默认值。
这导致结论是方法调用可以简化为:
NSLocalizedString("key", comment: "comment")
斯威夫特5 - 没有变化,仍然像那样。
现有答案的变体:
Swift 4.2:
extension String {
func localized(withComment comment: String? = nil) -> String {
return NSLocalizedString(self, comment: comment ?? "")
}
}
然后,您可以在有或没有评论的情况下使用它:
"Goodbye".localized()
"Hello".localized(withComment: "Simple greeting")
请注意,genstrings
不适用于此解决方案。
通过使用这种方式,可以为不同类型(即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 :)")
为案例创建了一个小帮助方法,其中“comment”始终被忽略。更少的代码更容易阅读:
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: "")
}
}
可能最好的方法是这一个here。
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)
对我来说这是最好的因为
实际上,您可以使用两个阶段来翻译Swift项目中的文本:
1)第一阶段是使用旧方法创建所有可翻译字符串:
NSLocalisedString("Text to translate", comment: "Comment to comment")
1.1)然后你应该使用genstrings来生成Localizable.strings:
$ genstrings *swift
2)之后,你应该使用这个answer。
2.1)根据正则表达式使用XCode“查找和替换”选项。至于给定的例子(如果你没有评论),正则表达式将是:
NSLocalizedString\((.*)\, comment:\ \"\"\)
并替换它
$1.localized
或者(如果你有评论)
NSLocalizedString\((.*)\, comment:\ (.*)\)
并替换它
$1.localizedWithComment(comment: $2)
您可以随意使用正则表达式和不同的扩展名组合。一般方法是将整个过程分为两个阶段。希望有所帮助。
在开发SDK时。你需要一些额外的操作。
1)在YourLocalizeDemoSDK中像往常一样创建Localizable.strings。
2)在YourLocalizeDemo中创建相同的Localizable.strings。
3)找到YourLocalizeDemoSDK的Bundle Path。
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
,你会得到一个错误的值(实际上它与键的字符串相同)。
但是如果你想使用dr OX提到的String扩展名。你需要做更多。原始扩展名如下所示。
extension String {
var localized: String {
return NSLocalizedString(self, tableName: nil, bundle: Bundle.main, value: "", comment: "")
}
}
我们知道,我们正在开发一个SDK,Bundle.main
将获得YourLocalizeDemo捆绑包。那不是我们想要的。我们需要YourLocalizeDemoSDK中的包。这是一个快速找到它的技巧。
在YourLocalizeDemoSDK中的NSObject实例中运行以下代码。您将获得YourLocalizeDemoSDK的URL。
let bundleURLOfSDK = Bundle(for: type(of: self)).bundleURL
let mainBundleURL = Bundle.main.bundleURL
打印两个url,你会发现我们可以在mainBundleURL上构建bundleURLofSDK。在这种情况下,它将是:
let bundle = Bundle(url: Bundle.main.bundleURL.appendingPathComponent("Frameworks").appendingPathComponent("YourLocalizeDemoSDK.framework")) ?? Bundle.main
String扩展名为:
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: "")
}
}
希望能帮助到你。