我正在创建快速应用程序。它包含Localizable.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

其中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")
    }}
}

最后,我可以像这样调用字符串:
label.text = String.lib_app_name

这只是我的主意,但我需要自己做所有这些,所以我只是想知道是否有更好或更流行的解决方案?我计划对资产名称和情节提要进行相同的操作,但也许有更好的方法来处理此问题?

最佳答案

dr_barto对。 SwiftGen是从字符串文件生成代码的好工具。

细节

  • Xcode版本10.3(10G8),Swift 5



  • 播客文件
    target 'stackoverflow-46981208' do
      use_frameworks!
      pod 'SwiftGen'
    end
    

    运行脚本
    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;
    

    ios - 如何自动生成Localizable.strings列表-LMLPHP

    文件结构

    ios - 如何自动生成Localizable.strings列表-LMLPHP

    Localizable.strings
    "Basic.Hello" = "Hello";
    
    "Auth.SignIn.Login" = "Login";
    "Auth.SignIn.Password" = "Password";
    

    用法
    print(L10n.Basic.hello)
    

    生成的代码样本
    // 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 {}
    

    结果

    ios - 如何自动生成Localizable.strings列表-LMLPHP

    07-28 03:45
    查看更多