Ios 什么';s NSLocalizedString在Swift中的等效值?
是否有类似于NSLocalizedString(…)的Swift? 在Ios 什么';s NSLocalizedString在Swift中的等效值?,ios,swift,localization,nslocalizedstring,Ios,Swift,Localization,Nslocalizedstring,是否有类似于NSLocalizedString(…)的Swift? 在Objective-C中,我们通常使用: NSString *string = NSLocalizedString(@"key", @"comment"); 如何在Swift中实现同样的目标?我发现了一个函数: func NSLocalizedString( key: String, tableName: String? = default, bundle: NSBundle = default,
Objective-C
中,我们通常使用:
NSString *string = NSLocalizedString(@"key", @"comment");
如何在Swift中实现同样的目标?我发现了一个函数:
func NSLocalizedString(
key: String,
tableName: String? = default,
bundle: NSBundle = default,
value: String = default,
#comment: String) -> String
但是,它很长,一点也不方便。Swift的世界中也存在着
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")
Swift 5-没有变化,仍然可以这样工作。我使用下一个解决方案:
1) 创建扩展名:
extension String {
var localized: String {
return NSLocalizedString(self, tableName: nil, bundle: Bundle.main, value: "", comment: "")
}
}
2) 在可本地化的.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) 使用:
通过使用这种方式,可以为不同的类型创建不同的实现(即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 :)")
为始终忽略“注释”的情况创建了一个小的辅助方法。代码越少,越容易阅读:
public func NSLocalizedString(key: String) -> String {
return NSLocalizedString(key, comment: "")
}
只要把它放在任何地方(类之外),Xcode就会找到这个全局方法。在单元测试中使用的帮助信息:
extension String {
func localized(withComment comment: String? = nil) -> String {
return NSLocalizedString(self, comment: comment ?? "")
}
}
这是一个简单的版本,可以扩展到不同的用例(例如使用表名)
像这样使用它:
NSLocalizedString("YOUR-KEY", referenceClass: self)
或者像这样加上一句评论:
NSLocalizedString("YOUR-KEY", referenceClass: self, comment: "usage description")
Swift 3版本:)
当你需要翻译时,比如说从一个短语相同的英语翻译到另一个不同的语言(因为性别、动词变位或变位)Swift中最简单的、适用于所有情况的字符串形式是三个参数一。例如,英语短语“previous was”在“weight”(重量)和“腰围”(腰围)的翻译与俄语不同 在这种情况下,一个源需要两种不同的翻译(根据WWDC 2018中推荐的XLIFF工具)。您无法使用两个参数NSLocalizedString实现它,其中“键”和英文翻译(即值)的“previous was”将是相同的。唯一的方法是使用三参数形式
NSLocalizedString("previousWasFeminine", value: "previous was", comment: "previousWasFeminine")
NSLocalizedString("previousWasMasculine", value: "previous was", comment: "previousWasMasculine")
其中键(“PreviousWasNegimal”和“PreviousWasMangimal”)不同
我知道一般的建议是把这个短语作为一个整体来翻译,然而,有时它太费时和不方便。也许最好的方法就是这个方法 及 你可以这样使用它
let message: String = .ThisApplicationIsCreated
print(message)
对我来说这是最好的,因为
- 硬编码字符串位于一个特定的文件中,因此在您想要更改它的那天,它非常容易
- 比每次在文件中手动键入字符串更容易使用
- 发电机串仍能工作
- 您可以添加更多扩展,例如每个视图控制器一个扩展,以保持整洁
NSLocalisedString("Text to translate", comment: "Comment to comment")
1.1)然后应使用genstring生成可本地化的.strings:
$ genstrings *swift
2) 之后,你应该使用这个
2.1)使用基于正则表达式的XCode“查找并替换”选项。
对于给定的示例(如果没有注释),正则表达式将是:
NSLocalizedString\((.*)\, comment:\ \"\"\)
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: "")
}
}
并将其替换为
$1.localized
$1.localizedWithComment(comment: $2)
或者(如果您有意见)
并将其替换为
$1.localized
$1.localizedWithComment(comment: $2)
您可以随意使用正则表达式和不同的扩展组合。一般的方法是将整个过程分为两个阶段。希望这能有所帮助。我已经创建了自己的GenString类工具,用于使用自定义翻译函数提取字符串
extension String {
func localizedWith(comment:String) -> String {
return NSLocalizedString(self, tableName: nil, bundle: Bundle.main, value: "", comment: comment)
}
}
它将解析所有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
这样可以组织消息并使genstring工作
这是使用的genstrings命令
find ./ -name \*.swift -print0 | xargs -0 genstrings -o .en.lproj
现有答案的变化: Swift 5.1:
extension String {
func localized(withComment comment: String? = nil) -> String {
return NSLocalizedString(self, comment: comment ?? "")
}
}
然后,您可以简单地使用它并添加或不添加注释:
"Goodbye".localized()
"Hello".localized(withComment: "Simple greeting")
请注意
genstrings
不能与此解决方案一起使用。当您开发SDK时。你需要做些额外的手术
1) 像往常一样在LocalizeDemoSDK中创建可本地化的.strings
let bundleURLOfSDK = Bundle(for: type(of: self)).bundleURL
let mainBundleURL = Bundle.main.bundleURL
2) 在LocalizeDemo中创建相同的可本地化字符串
3) 找到LocalizeDemoSDK的捆绑路径
let bundleURLOfSDK = Bundle(for: type(of: self)).bundleURL
let mainBundleURL = Bundle.main.bundleURL
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))
帮助您在LocalizeDemoSDK中找到该Bundle。如果改用Bundle.main
,则会得到一个错误的值(实际上,它与键是同一个字符串)
但是如果您想使用中提到的字符串扩展名。你需要多做一些。原点扩展如下所示
extension String {
var localized: String {
return NSLocalizedString(self, tableName: nil, bundle: Bundle.main, value: "", comment: "")
}
}
正如我们所知,我们正在开发一个SDK,Bundle.main将获得YourLocalizeDemo的Bundle包。这不是我们想要的。我们需要您的本地化DemoSDK中的捆绑包。这是一个快速找到它的技巧
在LocalizeDemoSDK中的NSObject实例中运行以下代码。您将获得LocalizeDemoSDK的URL
let bundleURLOfSDK = Bundle(for: type(of: self)).bundleURL
let mainBundleURL = Bundle.main.bundleURL
打印这两个url,您将发现
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: "")
}
}
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: "")
}
}
extension String {
func localized (bundle: Bundle = .main, tableName: String = "Localizable") -> String {
return NSLocalizedString(self, tableName: tableName, value: "\(self)", comment: "")
}
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
class BasicLabel: UILabel {
//initWithFrame to init view from code
override init(frame: CGRect) {
super.init(frame: frame)
setupView()
}
//initWithCode to init view from xib or storyboard
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
setupView()
}
//common func to init our view
private func setupView() {
let storyboardText = self.text
text = storyboardText?.localized()
}
}
class BasicBtn: UIButton {
//initWithFrame to init view from code
override init(frame: CGRect) {
super.init(frame: frame)
setupView()
}
//initWithCode to init view from xib or storyboard
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
setupView()
}
//common func to init our view
private func setupView() {
let storyboardText = self.titleLabel?.text
let lclTxt = storyboardText?.localized()
setTitle(lclTxt, for: .normal)
}
}
genstrings -SwiftUI *.swift -s localize -o .