iOS / iPhone:嵌套的Localizable.strings文件?

IOS/iPhone: Nested Localizable.strings Files?

我正在创建一个具有多种变体的应用。

这些变体将由多个Localizable.strings文件中的几个字符串控制。

但是,90%的字符串将保持不变。

我想拥有它,以便每个唯一的Localizable.strings文件都导入"主"文件,这样,当我想更改通用文件时,不必遍历每个应用程序变体文件。字符串。

这可能吗?


两种选择:

  • NSLocalizedString周围使用自定义package器功能为您进行分层查找,然后使用默认情况下的NSLocalizedString机制。

    我以前写过有关如何执行此操作的答案:.strings资源文件可以在运行时添加吗?

  • 每种语言使用多个.strings文件。默认情况下,在" Localizable.strings"中查找内容,但是NSLocalizedStringFromTable()函数允许您指定自定义的"表"名称。因此,如果您将" Configuration"作为表名传递,它将在" Configuration.strings"文件中查找内容。

    我开发了一个执行此操作的应用程序。我们有两个不同的.strings文件。一个控制品牌设置(使用的名称,使用的图像,使用的服务器等),另一个控制所有实际翻译的字符串。应用程序捆绑包中只有一个品牌信息副本,我们选择了正确的变体以在编译时与一些自定义脚本一起使用。它的工作真的非常好。


  • 不幸的是,Apple不支持其Localizable.strings文件。

    您可以使用sed通过自定义的Ruby或Python脚本或仅是Bash脚本来模仿该功能;该脚本可以获取根.strings文件并将其内容复制到每个变体的.strings文件中。它甚至可能是Xcode中的自定义构建步骤。


    为具有公共字符串的所有目标创建一个Localizable.strings。还要为每个目标创建TargetSpecificLocalizable.strings并将目标特定的字符串放入其中。然后对于常见的字符串使用

    1
    NSLocalizedString("sample string", comment:"")

    ,对于目标特定的字符串,请使用

    1
    NSLocalizedString("sample string", tableName:"TargetSpecificLocalizable", bundle: Bundle.main, value:"", comment:"")


    好。这是我为解决此问题所做的工作。

    我从Git存储库中删除了各种Localizable.strings文件,但是将它们保留在它们的位置(每个应用程序变体目录中的一个)。

    我只提取了每个变体之间不同的几行,并将它们分成一个单独的文本文件,称为" MyLocalizable.strings"。我将它们添加到Git中,然后将它们添加到项目中,而无需将它们与目标相关联。我离开了与每个目标相关联的Localizable.strings文件。

    因此,我们拥有的每个目标都有一个与目标关联的Localizable.strings文件,该文件将被复制到捆绑包中。每个目标目录都有一个名为" MyLocalizable.strings"的文件,该文件仅包含少数几个因目标而异的字符串。

    然后,我将绝大部分不变的字符串放入了另一个名为" MyLocalizable.strings"的文件中,并将其放在中央(公用)目录中。同样,我将其添加到Git和项目中,而无需将其与目标关联。

    然后,我写了一个很小的,可怜的Perl脚本,从给定目标中的通用文件构造了Localizable.strings文件,并附加了特定于目标的文件。这将覆盖现有的Localizable.strings文件。这意味着对于脚本的每次运行,Localizable.strings文件都是新的。该脚本放置在公共区域中,并且已添加到项目中,而无需将其与目标关联。该脚本有一个参数,它是目标(及其目录)的名称。该脚本的语法为:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    #!/usr/bin/perl

    use strict;         # I'm anal. What can I say?
    use Cwd;            # We'll be operating on the working directory.
    use File::Path;

    my $input1File = cwd()."/BMLT/Supporting\\ Files/en.lproj/MyLocalizable.strings";
    my $input2File = cwd()."/".$ARGV[0]."/en.lproj/MyLocalizable.strings";
    my $outputFile = cwd()."/".$ARGV[0]."/en.lproj/Localizable.strings";

    open ( MAIN_FILE, $input1File ) || die ("Could not open main file!" );

    my @file_data = <MAIN_FILE>;

    close ( MAIN_FILE );

    open ( PRODUCT_FILE, $input2File ) || die ("Could not open product file!" );

    push ( @file_data, <PRODUCT_FILE> );

    close ( PRODUCT_FILE );

    open ( FINAL_FILE,">$outputFile" ) || die ("Could not open destination file!" );

    foreach ( @file_data ) print FINAL_FILE $_;

    close ( FINAL_FILE );

    然后在"复制捆绑包资源"步骤之前添加"运行脚本"构建步骤。该脚本使用以下语法调用Perl脚本:

    1
    ${PROJECT_DIR}/BMLT/Supporting\\ Files/buildLocalizationFile.pl ${PRODUCT_NAME}

    构建后,将文件合并,并将合并后的文件放入捆绑包中。


    我不确定您想要什么,但是如果您只想翻译一些字符串,就可以。

    您可以只翻译这些字符串的一部分,如果没有翻译,ios将选择应用程序语言中的字符串并显示出来。因此,可以将应用程序语言中的Localizable.strings视为主语言。