I. Internationalization of two types of documents
Internationalization of. m files in code
First, add a layer of nslocalizedstring to the string you need to deal with internationally, and be aware of Chinese.
Textfield.text = [NSString stringwithformat:nslocalizedstring (@ "Use Help", nil)];
Nslocalizedstring is a macro defined in NSBundle.h that is used to find the value of a key in the Localizable.strings file that corresponds to the current system language.
The first parameter is the name of the key, and the second parameter is a comment on the "key-value pair", which is automatically added when generating the Localizable.strings file with the Genstrings tool.
When we have modified all the. m files, we can use the Genstrings tool.
1. Start the terminal and enter the directory where the project is located.
2. Create a new two directory, recommended in the resource directory.
The directory name will function to the language of the Localizable.strings file and cannot be written incorrectly. Here Zh-hans refers to Simplified Chinese, note can not be expressed in zh.lproj.
mkdir zh-hans.lproj
mkdir en.lproj
3. Generate the Localizable.strings file
Genstrings-o zh-hans.lproj *.M
Genstrings-o en.lproj *.M
-O < folder; Specifies the directory where the generated localizable.strings file is placed.
*.M, scan all the. m files. The files supported here also include. h,. Java, and so on.
If you think this is the end, then too naive, in fact, the above genstrings instruction can only be the directory of the file traversal, but not recursive traversal, so in some large projects obviously can not meet the requirements, so in the project more common usage is
Find./-name *.M | Xargs Genstrings-o En.lproj
This is the legendary shell combination Directive Find+xargs,find./-name *.M will recursively return all. m files and there is an array that is passed through the pipe to the next instruction, and Xargs will divide the received array one by one and give it to genstrings to execute.
So that we can get the following file structure
International Treatment of Storyboard
read the documentation or other introductions know that the internationalization of storyboard is very simple, here is a brief introduction
1 PROJECT---Info-localizations here to add the language you want to increase
2 Storyboard The Inspector column of the localization (left), project file Navigator There will be a few more files (figure right)
2 internationalization follow-up optimization
The shortcomings
In fact, the internationalization of iOS has been completed, but you may also find a problem, the above two methods are all a one-time generation of files, but our projects are often updated constantly. Re-run the above process, the resulting string file will overwrite the previously translated file.
The internationalization of the code is OK, after all, the general face of new requirements we will create new classes and files, as long as the new code files into a folder, execute genstrings can get a copy of the corresponding localization file, and then to the translator, Finally, the translated key-value pairs are appended to the end of the original localizable.string file.
and storyboard internationalization can not be so, of course, a new storyboard is also possible, but if it is a small change we generally will be in the original storyboard there to add controls, this time, The internationalization of the original storyboard new controls is the focus of our work today.
Solution Solutions
Carefully observe the storyboard translation file, you will find here is also a key value pair, key is the control id+ state, the value is the display text. Assuming that we have a translation of the file A, add the control, we do an internationalization directive, generate file B, we take A and b contrast, the number of keys in the B is inserted in the end of a file, A is in a and B does not have a key value pair deleted (that is, the control is deleted), In this way we have updated the storyboard translation file. This step can be done with script files, and Xcode's run script provides scripting support, allowing us to execute the script after the build.
Script code
#!/usr/bin/env python# encoding:utf-8 "" "Untitled.pycreated by Linyu on 2015-02-13.copyright (c) __MyCompanyName__. All rights reserved. "" " Import IMP Import sys import osimport globimport string import re import timeimp.reload (SYS) sys.setdefaultencoding (' UTF -8 ') #设置默认编码, can only be utf-8, below \u4e00-\u9fa5 required ksourcefile = ' base.lproj/*.storyboard ' ktargetfile = ' *.lproj/*.strings ' Kgeneratestringsfile = ' tempfileofstoryboardnew.strings ' colonregex = ur ' ["] (. *?) ["] ' Keyparamregex = ur ' ["] (. *?) ["] (\s*) = (\s*) ["] (. *?) ["];‘ anotationregexprefix = Ur '/(. *?) /' Def getcharaset (string_txt): Filedata = ByteArray (String_txt[:4]) if Len (filedata) < 4:return 0if (filedata[0] = = 0xE F) and (filedata[1] = = 0xBB) and (filedata[2] = 0xBF):p rint ' Utf-8 ' return 1elif (filedata[0] = = 0xFF) and (filedata[1] = = 0xFE) and (filedata[2] = = 0x00) and (filedata[3] = = 0x00):p rint ' utf-32/ucs-4,little endian ' return 3elif (filedata[0] = = 0x00) and (filedata[1] = = 0x00) and (filedata[2] = = 0xFE) and (filedata[3] = = 0xFF):print ' Utf-32/ucs-4,big endian ' return 3elif (filedata[0] = = 0xFE) and (filedata[1] = 0xFF):p rint ' Utf-16/ucs-2,little end Ian ' Return 2elif (filedata[0] = = 0xFF) and (filedata[1] = = 0xFE):p rint ' Utf-16/ucs-2,big endian ' return 2else:print ' can no T recognize! ' Return 0def Decoder (string_txt): var = getcharaset (string_txt) If var = = 1:return String_txt.decode ("Utf-8") elif var = 2:r Eturn String_txt.decode ("utf-16") elif var = 3:return String_txt.decode ("utf-32") Else:return String_txtdef Constructanotationregex (str): return anotationregexprefix + ' \ n ' + strdef getanotationofstring (string_txt,suffix): Anotationregex = Constructanotationregex (suffix) anotationmatch = Re.search (anotationregex,string_txt) anotationstring = "If Anotationmatch:match = Re.search (anotationregexprefix,anotationmatch.group (0)) if match: anotationstring = Match.group (0) return anotationstringdef comparewithfilepath (newstringpath,originalstringpath): # Read Newstringfile Nspf=open (Newstringpath, "r") #newString_txt = str (nspf.reaD (5000000)). Decode ("utf-16") Newstring_txt = Decoder (str (nspf.read)) 5000000 () Nspf.close = {} Anotation_dic = {}for stfmatch in Re.finditer (Keyparamregex, newstring_txt): Linestr = Stfmatch.group (0) anotationString = Getanotationofstring (newstring_txt,linestr) Linematchs = Re.findall (Colonregex, Linestr) If Len (linematchs) = = 2: Leftvalue = Linematchs[0]rightvalue = Linematchs[1]newstring_dic[leftvalue] = Rightvalueanotation_dic[leftvalue] = Anotationstring#read originalstringfile Ospf=open (Originalstringpath, "r") Originalstring_txt = Decoder (str ( Ospf.read (5000000)) ospf.close () Originalstring_dic = {}for stfmatch in Re.finditer (Keyparamregex, OriginalString_txt ): Linestr = Stfmatch.group (0) Linematchs = Re.findall (Colonregex, Linestr) If Len (linematchs) = = 2:leftvalue = linematchs[ 0]rightvalue = Linematchs[1]originalstring_dic[leftvalue] = Rightvalue#compare and remove the useless param in original St Ringfor key in Originalstring_dic:if (key not in newstring_dic): Keystr = ' "%s" '%KEYREPLACESTR = '//' +keystrmatch = Re.search (Replacestr, originalstring_txt) if match is None:originalstring_txt = Origin Alstring_txt.replace (KEYSTR,REPLACESTR) #compare and add new param to original stringexecuteonce = 1for key in Newstring_di C:values = (key, Newstring_dic[key]) if (key not in originalstring_dic): newline = "if executeonce = = 1:timestamp = Time.str Ftime ('%y-%m-%d%h:%m:%s ', Time.localtime (Time.time ())) newline = ' \n//############################################ ######################################\n ' newline+= '//# autogenstrings ' +timestamp+ ' \ n ' newline+= '//### ###############################################################################\n ' executeOnce = 0newline + = ' \ n ' + Anotation_dic[key]newline + = ' \ n '%s ' = '%s '; \ n '%valuesoriginalstring_txt + newline#write into origial filesbfw=open ( Originalstringpath, "W") Sbfw.write (Originalstring_txt) sbfw.close () def extractfilename (file_path): seg = File_ Path.split ('/') lastindex = Len (seg)-1return seg[lastindex]def Extractfileprefix (file_path): seg = file_path.split ('/') lastindex = Len (seg)-1prefix = Seg[lastindex].split ('. ') [0]return prefixdef Generatestoryboardstringsfile (storyboard_path,tempstrings_path): cmdstring = ' Ibtool ' + storyboard_path+ '--generate-strings-file ' +tempstrings_pathif os.system (cmdstring) = = 0:return 1def main (): FilePath = Sys.argv[1]sourcefilepath = FilePath + '/' + ksourcefile sourcefile_list = Glob.glob (Sourcefilepath) If Len (sourcefile_ list) = = 0:print ' ERROR dictionary,you should choose the dic upper the base.lproj ' Returntargetfilepath = FilePath + '/' + Ktargetfiletargetfile_list = Glob.glob (targetfilepath) Tempfile_path = FilePath + '/' + Kgeneratestringsfileif len ( targetfile_list) = = 0:print ' ERROR framework, No. lproj DIC is found ' returnfor SourcePath in Sourcefile_list:sourceprefi x = Extractfileprefix (sourcepath) SourceName = Extractfilename (sourcepath) print ' init with%s '%sourcenameif Generatestoryboardstringsfile (sourcepath,tempfile_path) = = 1:print '--genstRings%s successfully '%sourcenamefor TargetPath in targetfile_list:targetprefix = Extractfileprefix (TargetPath) TargetName = Extractfilename (TargetPath) if CMP (sourceprefix,targetprefix) = = 0:print '--dealing with%s '%targetpathcom Parewithfilepath (tempfile_path,targetpath) print ' Finish with%s '%sourcenameos.remove (tempfile_path) else:print '-- Genstrings%s error '%sourcenameif __name__ = = ' __main__ ': Main ()
1 Create a new folder RunScript, storing the Python script, placed in the directory of the project file,
In order to be intuitive you can drag the folder into the project (not to do so)
2 target->build phases->new Run Script Phase, write the following instruction in the shell
Python ${srcroot}/${target_name}/runscript/autogenstrings.py ${srcroot}/${target_name}
3 Add a TextField control in storyboard, and then Bulid, after successful we open the translation file, send the following text added
4 We do not need to run the script every time the build, so when you do not need, you can select the run script in step 2 when installing, so that he will not run the script, for specific reasons interested in Baidu can be his own.
Here's the GitHub address for the program:
Https://github.com/linyu92/MyGitHub
iOS internationalization-Storyboard translation from scripting