如何正确使用VarArgs本地化字符串?

fan*_*ncy 4 ios swift swift3

我有一个String扩展,可以帮助我国际化.

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

    func localized(args:CVarArg...) -> String{
        return NSString.localizedStringWithFormat(self.localized as NSString, args) as String
    }
}
Run Code Online (Sandbox Code Playgroud)

这样我就可以轻松地在应用程序的任何地方使用"hello_world".localized,它可以很好地工作.

现在我想拥有相同的功能,但也希望能够传递参数.然而,传递'CVarArg ......'似乎并不像我期望的那样有效.

"grant_gps_access".localized("MyApp")

预期结果:"请授予MyApp GPS访问权限"

实际结果:"请授予(\n MyApp \n)GPS访问权限"

我在这里错过了什么?

Mar*_*n R 10

你不能将变量参数列表传递给另一个函数,你必须传递一个CVaListPointer(va_list在C中的Swift等价物):

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

    func localized(args: CVarArg...) -> String {
        return withVaList(args) {
            NSString(format: self.localized, locale: Locale.current, arguments: $0) as String
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

由于NSString.localizedStringWithFormat没有变量采用a VAListPointer,因此NSString(format:, locale:, arguments:) 使用与当前语言环境等效的变体 .

更简单(归属于@OOPer):使用 String.init(format:locale:arguments:)带 [CVarArg]参数:

    func localized(args: CVarArg...) -> String {
        return String(format: self.localized, locale: Locale.current, arguments: args)
    }
Run Code Online (Sandbox Code Playgroud)

现在

"grant_gps_access".localized(args: "MyApp")
Run Code Online (Sandbox Code Playgroud)

应该按预期工作,假设字符串文件包含条目

"grant_gps_access" =  "Please grant %@ GPS access";
Run Code Online (Sandbox Code Playgroud)