如何自动生成 Localized.strings 列表

mam*_*rka 1 xcode ios swift

我正在创建快速应用程序。它包含 Localized.strings 文件中的一些字符串。每次我想使用它时,我都需要通过它的 id 来获取它。一开始我用它们创建了一个枚举,但每次添加新文本时手动添加它有点烦人。我试图使这个过程更简单,并将新的脚本阶段添加到 xcode 构建阶段。该脚本为我创建字符串扩展类,然后逐行读取可本地化文件,查找引号之间的单词并将其转换为字符串变量。一般来说,它看起来如下:

echo "
import Foundation

extension String {

    " > Classes/Constants/StringId.swift



while IFS= read -r line;do

PREFIX="static var"
VAR_NAME=`echo $line| awk -F \" '{print $2}'`
SUFFIX_1=": String {
get {
    return String.from(core: \"$VAR_NAME\")
}}"
SUFFIX_2="\""

if [ -z "$VAR_NAME" ]
then
echo "empty"
else
echo "$PREFIX lib_$VAR_NAME $SUFFIX_1"  >> Classes/Constants/StringId.swift
fi
done < Resources/Base.lproj/Localizable.strings
Run Code Online (Sandbox Code Playgroud)

其中 String.from... 是我从正确的资源文件中获取字符串的内部方法(如通用字符串、可访问性字符串或可标记字符串)。

结果我有一个具有以下结构的类:

import Foundation

    extension String {


    static var lib_author_website : String {
    get {
        return String.from(core: "author_website")
    }}
    static var lib_author_name : String {
    get {
        return String.from(core: "author_name")
    }}
    static var lib_app_name : String {
    get {
        return String.from(core: "app_name")
    }}
}
Run Code Online (Sandbox Code Playgroud)

最后我可以这样调用该字符串:

label.text = String.lib_app_name
Run Code Online (Sandbox Code Playgroud)

这只是我的想法,但我需要自己制作所有这些,所以我只是好奇是否有更好或更流行的解决方案?我计划对资产名称和故事板做同样的事情,但也许有更好的方法来处理这个问题?

Vas*_*huk 5

dr_barto right. SwiftGen is a good tool to generate code from strings files.

Details

  • Xcode Version 10.3 (10G8), Swift 5

Solution

Podfile

target 'stackoverflow-46981208' do
  use_frameworks!
  pod 'SwiftGen' 
end
Run Code Online (Sandbox Code Playgroud)

Run Script

TemplatePath=$PODS_ROOT/SwiftGen/templates
AppRoot=$PROJECT_DIR/stackoverflow-46981208
Resources=$AppRoot/Resources
LocalizationInput=$Resources/Localization/en.lproj/Localizable.strings
LocalizationOutput=$Resources/Localization/GeneratedStrings.swift

$PODS_ROOT/SwiftGen/bin/swiftgen strings $LocalizationInput -p $TemplatePath/strings/structured-swift4.stencil --output $LocalizationOutput;
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

Files structure

在此输入图像描述

Localizable.strings

"Basic.Hello" = "Hello";

"Auth.SignIn.Login" = "Login";
"Auth.SignIn.Password" = "Password";
Run Code Online (Sandbox Code Playgroud)

Usage

print(L10n.Basic.hello)
Run Code Online (Sandbox Code Playgroud)

Generated code sample

// swiftlint:disable superfluous_disable_command
// swiftlint:disable file_length

// MARK: - Strings

// swiftlint:disable explicit_type_interface function_parameter_count identifier_name line_length
// swiftlint:disable nesting type_body_length type_name
internal enum L10n {

  internal enum Auth {
    internal enum SignIn {
      /// Login
      internal static let login = L10n.tr("Localizable", "Auth.SignIn.Login")
      /// Password
      internal static let password = L10n.tr("Localizable", "Auth.SignIn.Password")
    }
  }

  internal enum Basic {
    /// Hello
    internal static let hello = L10n.tr("Localizable", "Basic.Hello")
  }
}
// swiftlint:enable explicit_type_interface function_parameter_count identifier_name line_length
// swiftlint:enable nesting type_body_length type_name

// MARK: - Implementation Details

extension L10n {
  private static func tr(_ table: String, _ key: String, _ args: CVarArg...) -> String {
    // swiftlint:disable:next nslocalizedstring_key
    let format = NSLocalizedString(key, tableName: table, bundle: Bundle(for: BundleToken.self), comment: "")
    return String(format: format, locale: Locale.current, arguments: args)
  }
}

private final class BundleToken {}
Run Code Online (Sandbox Code Playgroud)

Results

在此输入图像描述