Xcode Localizable.string 多目标问题

9
我有一个项目有多个目标,代表着同一个应用程序,只是具有不同的样式和翻译。
由于几乎整个项目对于每个目标看起来都是相同的,因此我只需要在Localizable.strings文件中有几个需要不同的字符串。我不想复制整个庞大的Localizable.strings文件到每个项目中,仅仅因为它有几行不同。
由于项目包含了第三方库/SDK,所以我需要只有1个字符串文件。因此我不能使用tableName来进行localizedString
问题是 - 我需要有一种灵活的可能性,可以分别覆盖每个目标中的Localizable.strings中的一些行。我不喜欢仅仅将整个文件复制到每个目标中的想法,因为这将导致将来繁琐的流程,如果我有10个目标,并且我需要向所有目标添加1个字符串。
目标是拥有一个包含所有字符串的庞大的Localizable.strings文件,该文件对于所有目标都是共同的,并为每个目标设置少量的配置,以便告诉哪些字符串应该不同。因此,目标文件应该合并和覆盖通用文件。
据我所知,Xcode不支持这种方式,因此我可能正在寻找一个可以使其正常工作的脚本。
因此,脚本应查看通用和目标的Localizable文件,将它们合并,并在某些键在两个文件中都被定义的情况下,它应该使用来自目标文件的键。
有人能帮我写这样的脚本吗?
P.S. .xcassets也存在类似的问题,CocoaPods通过将多个资源合并成1个来解决它,并且它按预期工作 - 如果一些目标具有包含已包含在公共资源中的相同名称的图像的资源,则来自目标的资源将替换它。
P.S.2. Android开发人员可以覆盖每个图像、每个翻译的类似功能是本地支持的。
2个回答

3

简而言之:

示例项目: https://github.com/JakubMazur/SO45279964


好的,编写Shell/Python脚本可能是最简单的方法,因为它适用于每个构建服务器。我假设您对每个目标都有不同的方案(否则将没有意义)。所以你可以这样做:

假设您的目标名称如下:

  • target1
  • target2
  • target3

1)创建包含所有应该不同的字符串的单独文件(我将放在Localizable目录下。

你的Localizable.strings文件可能是这样的:

"someGeneralString" = "General string 1";
"AppName" = "This is a string that you probably need to change";
"someOtherGeneralString" = "General string 2";

您的任何一个targetX.strings文件都可能如下所示:

"AppName" = "target[x]"

这是在您的项目中应该看起来像什么:

enter image description here

请注意,您的target本地化文件应该只设置为一个目标成员身份,但是您的Localizable.strings应该适用于所有目标!

这就是项目配置的全部内容。现在我们进入脚本编写(我将使用python):

#!/usr/bin/python

import sys

supportedLanguages = ["en","pl"]
commonPath = ".lproj/Localizable.strings"
keys = ["AppName"]

    class CopyLocalizable():

        target = ""

        def __init__(self,arg):
            self.target = arg
            self.perform()

        def perform(self):
            for lang in supportedLanguages:
                pathToLocalizable = lang+commonPath
                textToFile = ""
                with open(pathToLocalizable,"r") as languageFile:          
                    for line in languageFile.readlines():
                        for key in keys:
                            if key in line:
                                textToFile += self.foundAndReplace(key,lang)
                            else:
                                textToFile += line
                self.saveInFile(pathToLocalizable,textToFile)


        def foundAndReplace(self,key,lang):
            pathToTargetFile = "Localizable/"+lang+".lproj/"+self.target+".strings"
            with open(pathToTargetFile,"r") as targetFile:
                for targetLine in targetFile.readlines():
                    if key in targetLine:
                        return targetLine

        def saveInFile(self,file,stringToSave):
            with open(file,"w+") as languageFile:
                languageFile.write(stringToSave)

您可以自己进行优化。这是我能想到的最简单的脚本,可用于完成任务。

最后让我们自动化一下: - 进入您的目标 - 添加一个新的构建阶段 - 添加一个新的脚本:

export PATH="/usr/local/bin:$PATH"
cd SO45279964/
python localize.py target[x]

观看魔法即将发生;)

http://www.giphy.com/gifs/26n6NKgiwYvuQk7WU

在这里,您可以找到我创建的示例项目来运行此示例: https://github.com/JakubMazur/SO45279964


谢谢,Kuba。大部分都按照我的想法工作了。几点评论:1. 据我所知,我们甚至可以从构建中删除targetX文件,因为它们在项目中并没有被使用,因为我们使用通用的本地化文件。2. 我可能会将脚本重写为Ruby,这对我来说更友好,并使其不包含硬编码键。但无论如何,感谢您的想法和示例。 - Stas Ivanov
  1. 是的,这些文件与项目无关。
  2. 当然,正如我所写的那样,这是最简单的实现。你可以重写它(你应该这样做;)并且在上面的脚本中还有优化的空间,因为每个键都重新打开了文件。
祝编码愉快!
- Jakub

0
为了让事情变得简单,可以在构建设置中为每个目标定义一个宏,并在宏部分内定义特定于目标的字符串。
#ifdef __TARGET__
//key values in localizable file
#endif

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接