是否有一个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

但是,它很长,一点也不方便。


当前回答

现有答案的变体:

斯威夫特5.1:

extension String {

    func localized(withComment comment: String? = nil) -> String {
        return NSLocalizedString(self, comment: comment ?? "")
    }

}

然后你可以简单地使用它,带或不带注释:

"Goodbye".localized()
"Hello".localized(withComment: "Simple greeting")

请注意,genstring不能用于此解决方案。

其他回答

虽然这不能解决缩短的问题,但这帮助我组织消息,我为错误消息创建了一个如下所示的结构

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项目中使用两个阶段来翻译你的文本:

1)第一阶段是使用旧的方法来创建所有可翻译的字符串:

NSLocalisedString("Text to translate", comment: "Comment to comment")

1.1)然后你应该使用genstrings生成Localizable.strings:

$ genstrings *swift

2)之后,你应该使用这个答案。

2.1)基于正则表达式使用XCode的“Find and Replace”选项。 对于给定的例子(如果你没有注释),正则表达式将是:

NSLocalizedString\((.*)\, comment:\ \"\"\) 

并将其替换为

$1.localized

或者(如果你有意见的话)

NSLocalizedString\((.*)\, comment:\ (.*)\)

并将其替换为

$1.localizedWithComment(comment: $2)

您可以随心所欲地使用正则表达式和不同的扩展组合。一般的方法是把整个过程分成两个阶段。希望这能有所帮助。

当你在开发SDK时。你需要一些额外的操作。

1)创建Localizable。字符串通常在YourLocalizeDemoSDK。

2)创建相同的Localizable。字符串在YourLocalizeDemo。

3)找到你的捆绑路径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。如果你使用Bundle。相反,在Main中,您将得到一个错误的值(实际上它将是与键相同的字符串)。

但是如果你想使用OX博士提到的String扩展,你需要做更多的事情。原点扩展是这样的。

extension String {
    var localized: String {
        return NSLocalizedString(self, tableName: nil, bundle: Bundle.main, value: "", comment: "")
    }
}

正如我们所知,我们正在开发一个SDK, Bundle。main将获得YourLocalizeDemo的bundle。这不是我们想要的。我们需要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: "")
    }
}

希望能有所帮助。

也许最好的方法是这个。

fileprivate func NSLocalizedString(_ key: String) -> String {
    return NSLocalizedString(key, comment: "")
}

and

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仍然可以工作 你可以添加更多的扩展,比如每个视图控制器一个扩展来保持整洁

使用默认语言进行本地化:

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: "")
    }
}