我正在开发一个应用程序,它将有多个变种。
这些变种将由多个Localizable.strings文件中的一些字符串进行控制。
然而,90%的字符串都将保持不变。
我希望每个唯一的Localizable.strings文件都能导入“主”文件,这样当我想要更改通用字符串时,就不必逐个更改每个应用程序变体文件。
这种做法是否可行?
我正在开发一个应用程序,它将有多个变种。
这些变种将由多个Localizable.strings文件中的一些字符串进行控制。
然而,90%的字符串都将保持不变。
我希望每个唯一的Localizable.strings文件都能导入“主”文件,这样当我想要更改通用字符串时,就不必逐个更改每个应用程序变体文件。
这种做法是否可行?
两种选择:
使用自定义包装函数围绕 NSLocalizedString
来为您进行分层查找,然后在默认情况下回退到 NSLocalizedString
机制。
我之前写过一篇关于如何做到这一点的答案:Can .strings resource files be added at runtime?
每种语言使用多个 .strings 文件。默认情况下会在 "Localizable.strings" 中查找东西,但是 NSLocalizedStringFromTable()
函数允许您指定自定义的 "table" 名称。所以如果您传递 "Configuration" 作为表名,它将在 "Configuration.strings" 文件中查找东西。
我曾经在一个应用程序上工作过,它就是这么做的。我们有两个不同的 .strings 文件。一个控制品牌设置(使用什么名称、使用什么图像、使用什么服务器等),另一个包含所有实际翻译的字符串。应用程序包中只有一个品牌信息拷贝,并且我们使用一些自定义脚本在编译时选择要使用的正确变体。它运行得非常好。
很遗憾,苹果不支持在其 Localizable.strings
文件中实现该功能。
你可以通过编写自定义的 Ruby 或 Python 脚本或者使用 Bash 脚本(使用 sed
命令),来模拟此功能;该脚本可以将根目录的 .strings
文件的内容复制到每个变体的 .strings
文件中。甚至可以把它作为自定义构建步骤添加到 Xcode 中。
好的。这是我解决它的方法。
我从Git存储库中删除了各种Localizable.strings文件,但将它们留在它们的位置(每个应用程序变体目录中有一个)。
我只取了每个变体之间不同的几行,并将它们分成一个单独的文本文件,称为“MyLocalizable.strings”。我将它们添加到Git中,并将它们添加到项目中,但不与任何目标相关联。我将Localizable.strings文件与每个目标相关联。
因此,我们拥有的是每个目标都有一个与目标相关联并将被复制到bundle中的Localizable.strings文件。每个目标目录都有一个名为“MyLocalizable.strings”的文件,其中仅包含从目标到目标变化的少数字符串。
然后,我将绝大多数字符串 - 那些不会改变的字符串 - 放入另一个名为“MyLocalizable.strings”的文件中,并将其放置在中央(公共)目录中。同样,我将其添加到Git和项目中,但不与任何目标相关联。
接下来,我编写了一个非常小且可怜的Perl脚本,用于构建Localizable.strings文件。该脚本从公共文件中获取内容并将其附加到特定目标的文件中,从而创建一个新的Localizable.strings文件,并覆盖现有的文件。这意味着每次运行脚本时都会生成新的Localizable.strings文件。该脚本位于公共区域,并添加到项目中,但不与任何目标相关联。该脚本只需要一个参数,即目标名称(以及其目录)。其语法如下:
#!/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 );
${PROJECT_DIR}/BMLT/Supporting\ Files/buildLocalizationFile.pl ${PRODUCT_NAME}
当构建完成后,文件将被合并,并将合并的文件放入捆绑包中。
我不确定你想要什么,但如果你只是想翻译几个字符串,那么你可以这样做。
你可以只翻译这些字符串的一部分,如果没有翻译,iOS 将选择应用程序语言中的字符串并显示它。因此,应用程序语言中的 Localizable.strings 可以被视为主文件。
Localizable.strings
文件,包含共用字符。同时为每个目标创建TargetSpecificLocalizable.strings
文件,并将目标特定字符保存其中。对于共用字符,请使用。NSLocalizedString("sample string", comment: "")
NSLocalizedString("sample string", tableName: "TargetSpecificLocalizable", bundle: Bundle.main, value: "", comment: "")