Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/102.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Iphone NSLocalizedString通过应用程序版本管理翻译_Iphone_Ios_Objective C - Fatal编程技术网

Iphone NSLocalizedString通过应用程序版本管理翻译

Iphone NSLocalizedString通过应用程序版本管理翻译,iphone,ios,objective-c,Iphone,Ios,Objective C,下面是一个场景: 我使用NSLocalizedString编写了一个iPhone应用程序,以防我决定在不同的国家发布它 我决定在法国发布这个应用程序 翻译员将我的本地化.strings翻译得非常好 我更新了应用程序,需要更多的翻译 我正在使用genstrings,它覆盖了译者所做的出色工作,有没有一种简单的方法可以让我管理应用程序版本的翻译 查看GitHub,它提供了一个python脚本,可以使genstrings更智能一些 因为我不喜欢只链接的答案(链接可能会死),所以我也会把python脚本

下面是一个场景:

  • 我使用NSLocalizedString编写了一个iPhone应用程序,以防我决定在不同的国家发布它
  • 我决定在法国发布这个应用程序
  • 翻译员将我的
    本地化.strings
    翻译得非常好
  • 我更新了应用程序,需要更多的翻译
  • 我正在使用genstrings,它覆盖了译者所做的出色工作,有没有一种简单的方法可以让我管理应用程序版本的翻译

    查看GitHub,它提供了一个python脚本,可以使
    genstrings
    更智能一些

    因为我不喜欢只链接的答案(链接可能会死),所以我也会把python脚本放在这里(所有学分都归链接项目的作者所有)

    #/usr/bin/env python
    #-*-编码:utf-8-*-
    #Localize.py-XCode项目上的增量本地化
    #若昂·莫雷诺2009
    # http://joaomoreno.com/
    #由Steve Streeting 2010修改http://www.stevestreeting.com
    #变化
    #-使用编码为UTF-8的.strings文件
    #这是很有用的,因为Mercurial和Git将UTF-16视为二进制文件,不能
    #区分/合并它们。要在iPhone上使用,您可以在构建到的过程中运行iconv脚本
    #转换回UTF-16(MacOSX将乐于使用UTF-8.strings文件)。
    #-完成后清理旧文件和新文件
    #皮埃尔·杜拉克2012年修订http://friendcashapp.com
    #变化
    #-使用日志记录而不是打印
    #加上
    #-麻省理工学院执照
    #-命令行中用于指定*.lproj目录路径的第一个参数
    #-用于控制调试级别的可选参数(默认设置为info)
    #修复
    #-如果文件已在utf-8中,则不要转换该文件
    #-通过修改re_translation regex,允许genstring生成多行翻译
    # - 
    #麻省理工学院执照
    #
    #版权所有(C)2012 Pierre Dulac
    #
    #特此向获得本软件副本的任何人免费授予许可,以及
    #相关文档文件(“软件”),用于不受限制地处理软件,
    #包括但不限于使用、复制、修改、合并、发布、分发、再许可的权利,
    #和/或出售软件的副本,并允许向其提供软件的人员这样做,
    #符合下列条件:
    #
    #上述版权声明和本许可声明应包含在所有副本或实体中
    #部分软件。
    #
    #本软件按“原样”提供,无任何明示或暗示的担保,包括但不限于:
    #仅限于适销性、特定用途适用性和非侵权性的保证。
    #在任何情况下,作者或版权持有人均不对任何索赔、损害赔偿或其他责任负责,
    #无论是在合同诉讼、侵权诉讼或其他诉讼中,都是由以下原因引起的:
    #软件或软件的使用或其他交易。
    从系统导入argv
    从编解码器导入打开
    从重新导入编译
    从副本导入副本
    导入操作系统
    进口舒蒂尔
    导入optpass
    导入日志记录
    logging.getLogger().level=logging.INFO
    __版本=“0.1”
    __许可证\=“MIT”
    用法=“%prog[选项]”
    VERSION=“%prog v”+\u版本__
    重新翻译=编译(r'^“((?:[^“]\\”)+“=”((?:[^“]\\”)+);(?:\n)?$)
    re\u comment\u single=compile(r'^/\*.\*/$)
    re\u comment\u start=compile(r'^/\*.*.$)
    re_comment_end=compile(r'^.*\*/$)
    类LocalizedString():
    定义初始(自我、评论、翻译):
    self.comments,self.translation=注释,翻译
    self.key,self.value=re_translation.match(self.translation.groups)()
    def ___; unicode(自):
    返回u'%s%s\n'(u'。加入(self.comments),self.translation)
    类LocalizedFile():
    定义初始化(self,fname=None,auto\u read=False):
    self.fname=fname
    self.reset()
    如果自动读取:
    self.read_from_文件(fname)
    def重置(自):
    self.strings=[]
    self.strings_d={}
    def从_文件读取_(self,fname=None):
    self.reset()
    如果fname==无其他fname,则fname=self.fname
    尝试:
    #f=打开(fname,编码为'utf_8',模式为'r')
    f=打开(fname,编码为'utf_8',模式为'r')
    除:
    打印“文件%s不存在”。%fname
    出口(-1)
    尝试:
    line=f.readline()
    logging.debug(第行)
    除:
    日志记录。错误(“无法读取文件%s”%fname)的行)
    提升
    i=1
    while line:
    注释=[行]
    如果不重新注释单个匹配(行):
    while line and not re_comment_end.match(行):
    line=f.readline()
    注释.附加(行)
    line=f.readline()
    i+=1
    #处理多行
    而len(line)>1和line[-2]!=u';':
    行+=f.读行()
    i+=1
    logging.debug(“%d%s”%(i,line.rstrip('\n'))
    如果行和重新转换。匹配(行):
    翻译=行
    其他:
    logging.error(“引发异常的文件“%s”的第%d行:%s”%(i,self.fname,第行))
    引发异常('无效文件')
    line=f.readline()
    i+=1
    而line和line==u'\n':
    line=f.readline()
    i+=1
    字符串=本地化字符串(注释、翻译)
    self.strings.append(字符串)
    self.strings\u d[string.key]=string
    f、 关闭()
    def将_保存到_文件(self,fname=None):
    如果fname==无其他fname,则fname=self.fname
    尝试:
    f=打开(fname,编码为'utf_8',模式为'w')
    除:
    打印“无法打开文件%s”。%fname
    出口(-1)
    #按键排序
    self.strings.sort(key=lambda item:item.key)
    对于self.strings中的字符串:
    f、 写入(字符串)__
    
    #!/usr/bin/env python
    # -*- coding: utf-8 -*-
    
    # Localize.py - Incremental localization on XCode projects
    # João Moreno 2009
    # http://joaomoreno.com/
    
    # Modified by Steve Streeting 2010 http://www.stevestreeting.com
    # Changes
    # - Use .strings files encoded as UTF-8
    #   This is useful because Mercurial and Git treat UTF-16 as binary and can't
    #   diff/merge them. For use on iPhone you can run an iconv script during build to
    #   convert back to UTF-16 (Mac OS X will happily use UTF-8 .strings files).
    # - Clean up .old and .new files once we're done
    
    # Modified by Pierre Dulac 2012 http://friendcashapp.com
    # Changes
    # - use logging instead of print
    # Adds
    # - MIT Licence
    # - the first parameter in the command line to specify the path of *.lproj directories
    # - an optional paramter to control the debug level (set to info by default)
    # Fixes
    # - do not convert a file if it is already in utf-8
    # - allow multiline translations generated by genstrings by modifing the re_translation regex
    # - 
    
    # MIT Licence
    #
    # Copyright (C) 2012 Pierre Dulac
    #
    # Permission is hereby granted, free of charge, to any person obtaining a copy of this software and 
    # associated documentation files (the "Software"), to deal in the Software without restriction, 
    # including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, 
    # and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, 
    # subject to the following conditions:
    #
    # The above copyright notice and this permission notice shall be included in all copies or substantial 
    # portions of the Software.
    #
    # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT 
    # LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 
    # IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 
    # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 
    # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
    
    from sys import argv
    from codecs import open
    from re import compile
    from copy import copy
    import os
    import shutil
    import optparse
    import logging
    logging.getLogger().level = logging.INFO
    
    __version__ = "0.1"
    __license__ = "MIT"
    
    USAGE = "%prog [options] <url>"
    VERSION = "%prog v" + __version__
    
    re_translation = compile(r'^"((?:[^"]|\\")+)" = "((?:[^"]|\\")+)";(?:\n)?$')
    re_comment_single = compile(r'^/\*.*\*/$')
    re_comment_start = compile(r'^/\*.*$')
    re_comment_end = compile(r'^.*\*/$')
    
    class LocalizedString():
        def __init__(self, comments, translation):
            self.comments, self.translation = comments, translation
            self.key, self.value = re_translation.match(self.translation).groups()
    
        def __unicode__(self):
            return u'%s%s\n' % (u''.join(self.comments), self.translation)
    
    class LocalizedFile():
        def __init__(self, fname=None, auto_read=False):
            self.fname = fname
            self.reset()
    
            if auto_read:
                self.read_from_file(fname)
    
        def reset(self):
            self.strings = []
            self.strings_d = {}
    
        def read_from_file(self, fname=None):
            self.reset()
    
            fname = self.fname if fname == None else fname
            try:
                #f = open(fname, encoding='utf_8', mode='r')
                f = open(fname, encoding='utf_8', mode='r')
            except:
                print 'File %s does not exist.' % fname
                exit(-1)
    
            try:
                line = f.readline()
                logging.debug(line)
            except:
                logging.error("Can't read line for file: %s" % fname)
                raise
    
            i = 1
            while line:
                comments = [line]
    
                if not re_comment_single.match(line):
                    while line and not re_comment_end.match(line):
                        line = f.readline()
                        comments.append(line)
    
                line = f.readline()
                i += 1
    
                # handle multi lines
                while len(line) > 1 and line[-2] != u';':
                    line += f.readline()
                    i += 1
    
                logging.debug("%d %s" % (i, line.rstrip('\n')))
                if line and re_translation.match(line):
                    translation = line
                else:
                    logging.error("Line %d of file '%s' raising the exception: %s" % (i, self.fname, line))
                    raise Exception('invalid file')
    
                line = f.readline()
                i += 1
                while line and line == u'\n':
                    line = f.readline()
                    i += 1
    
                string = LocalizedString(comments, translation)
                self.strings.append(string)
                self.strings_d[string.key] = string
    
            f.close()
    
        def save_to_file(self, fname=None):
            fname = self.fname if fname == None else fname
            try:
                f = open(fname, encoding='utf_8', mode='w')
            except:
                print 'Couldn\'t open file %s.' % fname
                exit(-1)
    
            # sort by key
            self.strings.sort(key=lambda item: item.key)
    
            for string in self.strings:
                f.write(string.__unicode__())
    
            f.close()
    
        def merge_with(self, new):
            merged = LocalizedFile()
    
            for string in new.strings:
                if self.strings_d.has_key(string.key):
                    new_string = copy(self.strings_d[string.key])
                    new_string.comments = string.comments
                    string = new_string
    
                merged.strings.append(string)
                merged.strings_d[string.key] = string
    
            return merged
    
        def update_with(self, new):
            for string in new.strings:
                if not self.strings_d.has_key(string.key):
                    self.strings.append(string)
                    self.strings_d[string.key] = string
    
    def merge(merged_fname, old_fname, new_fname):
        try:
            old = LocalizedFile(old_fname, auto_read=True)
            new = LocalizedFile(new_fname, auto_read=True)
            merged = old.merge_with(new)
            merged.save_to_file(merged_fname)
        except Exception, inst:
            logging.error('Error: input files have invalid format.')
            raise
    
    STRINGS_FILE = 'Localizable.strings'
    
    def localize(path, excluded_paths):
        languages = [os.path.join(path,name) for name in os.listdir(path) if name.endswith('.lproj') and os.path.isdir(os.path.join(path,name))]
        print "languages found", languages
    
        for language in languages:
            original = merged = language + os.path.sep + STRINGS_FILE
            old = original + '.old'
            new = original + '.new'
    
            if os.path.isfile(original):
                try:
                    open(original, encoding='utf_8', mode='r').read()
                    os.rename(original, old)
                except:
                    os.system('iconv -f UTF-16 -t UTF-8 "%s" > "%s"' % (original, old))
    
                # gen
                os.system('find %s -name \*.m -not -path "%s" | xargs genstrings -q -o "%s"' % (path, excluded_paths, language))
    
                try:
                    open(original, encoding='utf_8', mode='r').read()
                    shutil.copy(original, new)
                except:
                    os.system('iconv -f UTF-16 -t UTF-8 "%s" > "%s"' % (original, new))
    
                # merge  
                merge(merged, old, new)
                logging.info("Job done for language: %s" % language)
            else:
                os.system('genstrings -q -o "%s" `find %s -name "*.m" -not -path "%s"`' % (language, path, excluded_paths))
                os.rename(original, old)
                try:
                    open(old, encoding='utf_8', mode='r').read()
                except:
                    os.system('iconv -f UTF-16 -t UTF-8 "%s" > "%s"' % (old, original))
    
            if os.path.isfile(old):
                os.remove(old)
            if os.path.isfile(new):
                os.remove(new)
    
    def parse_options():
        """parse_options() -> opts, args
    
        Parse any command-line options given returning both
        the parsed options and arguments.
        """
    
        parser = optparse.OptionParser(usage=USAGE, version=VERSION)
    
        parser.add_option("-d", "--debug",
                action="store_true", default=False, dest="debug",
                help="Set to DEBUG the logging level (default to INFO)")
    
        parser.add_option("-p", "--path",
                action="store", type="str", default=os.getcwd(), dest="path",
                help="Path (relative or absolute) to use for searching for *.lproj directories")
    
        parser.add_option("-e", "--exclude",
                action="store", type="str", default=None, dest="excluded_paths",
                help="Regex for paths to exclude ex. ``./Folder1/*``")
    
        opts, args = parser.parse_args()
        return opts, args
    
    if __name__ == '__main__':
        opts, args = parse_options()
        if opts.debug:
            logging.getLogger().level = logging.DEBUG
        if opts.path:
            opts.path = os.path.realpath(opts.path)
        if opts.excluded_paths:
            opts.excluded_paths = os.path.realpath(opts.excluded_paths)
        logging.info("Running the script on path %s" % opts.path)
        localize(opts.path, opts.excluded_paths)
    
    // In strings.h
    
     #define YOUR_STRING_KEY NSLocalizedString(@"Cancel", nil)
    
    // Somewhere else in you code
    
    NSLog(@"%@", YOUR_STRING_KEY);