1 Add an international language to be supported

  1. The parentheses following the added language are the international standard abbreviations for that language

  2. If you choose to add Japanese, the following dialog box will pop up. Just select Finish

  3. Add Japanese, French, Simplified Chinese and traditional Chinese as follows, you can find corresponding changes

2 Localize the app name

Localized App name: The name of the App, displayed as the corresponding name according to the device language Settings (~ for example, weChat App, displayed as weChat in Simplified Chinese and weChat in English)

2.1 Right-click the info.plist file and choose New file from the shortcut menu

2.2 Select Strings File as the File type

2.3 Specify the name asInfoPlist.strings(~ name must be InfoPlist~)

2.4 Created successfully

2.5 Select InfoPlist. Strings and click Localize in Xcode’s File Inspection (File inspector on the right side of Xcode) in order to select the language we need to Localize, as shown below:

Note: Before you click Localize, make sure you have added the required international language in step 1

2.6 The confirmation dialog box will pop up. By default, English is selected. You can select the preferred language you want to localize, or simply press the default and continue to add the international language you need later

2.7 After selecting the localized language, you can see that the InfoPlist. Strings file changes in the Locaization column of the file inspector bar

2.8 After other international languages are checked, you can see that the infolist. strings file also has multiple subitems changed

2.9 What happened from the project folder direction

The core idea of multilingual localization is to define a single resource for each language. IOS defines resources for each language through the xxx.lproj directory, where resources can be images, text, storyboards, xibs, etc

Each language has its own language code. Lproj folder, when loading resources, only the resources under the corresponding language folder need to be loaded, which can be completed by the system or manually

2.10 Set the display name of demo to: Localization test Demo

  • The key value of display name is displayed in the info.plist file

  • We know that the name of display name is the name displayed on the device after the App is installed

  • The CFBundleDisplayName key corresponding to the modified display name can be obtained by displaying the raw key value in info.plist

CFBundleDisplayName CFBundleName info.plist -Core Foundation Keys

So CFBundleDisplayName can be used for infoPlist. Strings.

2.11 Set localized App names on InfoPlist. Strings for different languages

/ / InfoPlist. Strings (English) files
CFBundleDisplayName = "EnglishDemo";


/ / InfoPlist. Strings (Chinese (Simplified) files
CFBundleDisplayName = "Simplified Demo";


/ / InfoPlist. Strings (Chinese) (Tradictional) files
CFBundleDisplayName = "Traditional Demo";


/ / InfoPlist. Strings (Japanese) files
CFBundleDisplayName = "Japanese Demo";


/ / InfoPlist. Strings (French) files
CFBundleDisplayName = "French Demo";
Copy the code

Note: CFBundleDisplayName may or may not use double quotation marks!

2.12 Obtaining the current language of the current simulator

// ViewController.m
@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    NSArray *languages = [[NSUserDefaults standardUserDefaults] valueForKey:@"AppleLanguages"];
    NSLog(@"AppleLanguages have %@", languages);
    NSString *currentLanguage = languages.firstObject;
    NSLog(@"Current simulator language: %@",currentLanguage);

}
Copy the code

2.13 Setting the language environment of the simulator

Set the language on your iOS device

2.14 Effect display of each language localization after running the program

  1. In traditional environment (current simulator language: zh-hant-HK)
// Run the result
2018-09-04 16:49:40.056223+0800 LanguageLocalizationDemo[92506:3273624] AppleLanguagesLanguage has ("zh-Hant-HK"."zh-Hans-US",
    en
)
2018-09-04 16:49:40.056505+0800 LanguageLocalizationDemo[92506:3273624] Emulator current language: zh-Hant-HK
Copy the code

  1. English environment (simulator current language: EN)
// Run the result
2018-09-04 17:00:37.811874+0800 LanguageLocalizationDemo[92874:3283615] AppleLanguagesLanguages have (en)2018-09-04 17:00:37.812133+0800 LanguageLocalizationDemo[92874:3283615[Emulator current language: enCopy the code

  1. In Japanese (simulator current language: JA-US)
2018-09-05 10:33:16.423697+0800 LanguageLocalizationDemo[46412:14218145]"ja-US", en) 2018-09-05 10:33:16.423941+0800 LanguageLocalizationDemo[46412:14218145Copy the code

  1. In Simplified Chinese (emulator current language: zh-Hans-us)
2018-09-05 10:36:18.376366+0800 LanguageLocalizationDemo[46510:14225868] AppleLanguages"zh-Hans-US"."zh-Hant-US"."ja-US", en) 2018-09-05 10:36:18.376628+0800 LanguageLocalizationDemo[46510:14225868Copy the code

  1. In French (emulator current language: FR-US)
2018-09-05 10:47:12.397641+0800 LanguageLocalizationDemo[46634:14239902] AppleLanguages ("fr-US"."zh-Hans-US"."zh-Hant-US"."ja-US", en) 2018-09-05 10:47:12.398086+0800 LanguageLocalizationDemo[46634:14239902Copy the code

Of course, after setting the corresponding language of the simulator, the name of the corresponding App will change with the system language when the simulator restarts. There is no need to run the project again. The purpose of running the above results is to observe the change of the system language and determine whether the language set is correct

2.15 Impact PassAppleLanguagesThe key fromNSUserDefaultsTo obtain the reasons for the supported languages

  1. Returns the result based on the language the device has ever added
NSArray *languages = [[NSUserDefaults standardUserDefaults] valueForKey:@"AppleLanguages"];
Copy the code

The NSArray *languages content obtained above is determined by which languages have been added to the current device. The emulator only has English by default, so you will see different results printed in 2.14

  1. Affected by Xcode language Settings Assume that simplified Chinese, traditional Chinese, English, French, and Japanese have been added to the device. 2.1 Added languages for devices

2.2 Causes in Xcode are set to follow the system by default

The array obtained by running the following code is:

NSArray *languages = [[NSUserDefaults standardUserDefaults] valueForKey:@"AppleLanguages"];
Copy the code
[2018-09-05 10:47:12.397641+0800] LanguageLocalizationDemo[46634:14239902]"fr-US"."zh-Hans-US"."zh-Hant-US"."ja-US", en) 2018-09-05 10:47:12.398086+0800 LanguageLocalizationDemo[46634:14239902Copy the code

The printed result is a normal added language on the device.

2.3 If the language in Xcode is set to a specified language (~ English~), the result is as follows:

2018-09-05 10:58:06.445970+0800 AppleLanguages [46726:14250118 10:58:06.446199+0800 LanguageLocalizationDemo[46726:14250118] Current language: ENCopy the code

There’s only one en element in the AppleLanguages array but the actual emulator language is still French, and the App name is still displayed in French depending on the device environment

The purpose of this comparison is to pay attention to these factors that affect device language acquisition in future development and debugging

Note also that the App name does not change with Xcode’s Application Langue, it only changes with the actual language of the device

Localize strings in code

The string in the localized code refers to the string in the program that displays different contents in different language environments. For example, the word “Home” is displayed in simplified Chinese, while Home is displayed in English.

The string flow in the localization code is basically the same as the localization App name, and the operation map of each step is also given below

3.1 Select the folder to save the newly created filecommand + nQuick File Creation

3.2 Set the File type to Strings File

3.3 Specifying the Strings File nameLocalizable

This name is used because it is the default name of the localization file loaded by the system, and we’ll talk later about modularizing localization and decoupling by customizing other names

3.4 Localize Localizable. Strings file

3.5 Select Other Languages

So far, the steps are the same as the localized App name, except for the name of the strings file

3.6 Write the character string to be localized in the corresponding language file in the key-value format

/ / Localizable. Strings (English) files"home" = "home"; / / Localizable. Strings (Chinese (Simplified) files"home" = "Simplified Homepage"; / / Localizable. Strings (Japanese) files"home" = "Japanese Home page"; / / Localizable. Strings (Chinese (Traditional) files"home" = "Traditional Homepage"; / / Localizable. Strings (French) files"home" = "French home";
Copy the code

3.7 throughNSLocalizedString(key, comment)This system provides macros that use the contents of localization files

  1. The environment language switch can be passedDevice language SettingsorScheme Settings in Xcode, it is recommended to use Xcode for quick Settings, so as to save the time waiting for the simulator to restart
  2. Here are the Settings to run
  • Simplified Chinese

  • English

  • French

  • Traditional Chinese

  1. NSLocalizedString macro definition parsing

  2. localizedStringForKey:value:table: – NSBundle

3.8 NSLocalizedString uses a trick

  1. When you use NSLocalizedString to search for strings files based on a given key, the default value returned is key if the value of the key cannot be found.
  • Localizable. Strings (English) file write nothing
  • NSLocalizedString uses the keylala
  • If the key cannot be found, it is returned as shown below:
  1. Assuming you use an English name for the key, the key-value pairs in the Localizable. Strings (English) file should normally look like this"home" = "home";Add key to Localizable. Strings (English) file (~ 😆~)

4 Modular management localization

4.1 Reasons for Modular Management

  1. As you can see from the third point, by building a file with the default name of Localizable. Strings, you can put all the code strings in your project that need to be localized into the Localizable. Strings file.
  2. However, although all in one place can be unified management, but with the increase of project modules and other situations, the content of the file will be bloated, although it can passannotationor#pragma mark - <#desc#>But when programming for more than one person, modifying a file at the same time leads to more complex problems

4.2 the custom.stringsFile, modular management

  1. Through NSLocalizedStringFromTable macros, a manual search strings specified file.
NSLocalizedStringFromTable(<#key#>, <#tbl#>, <#comment#>)
Copy the code
  1. Custom name · Strings file (module1.strings)

  2. Using NSLocalizedStringFromTable

5 Localize images

5.1 Method 1: The method is similar to localized code stringNSLocalizedStringGet the language picture name fromAssets.xcassetsTo obtain the corresponding picture

  • Using code examples

  • Assets. Xcassets name the picture

  • Corresponding to Localizable. Strings content

/ / Localizable. Strings (English) files"image-languge" = "english"; / / Localizable. Strings (Chinese (Simplified) files"image-languge" = "simplify"; / / Localizable. Strings (Japanese) files"image-languge" = "japan"; / / Localizable. Strings (Chinese (Traditional) files"image-languge" = "french"; / / Localizable. Strings (French) files"home" = "French home";
Copy the code
  • Running effect

    For other information, see Demo

5.2 Method 2: Specify the bundle’s images with localized properties (~ put the image resources in the corresponding language lproj folder ~)

  1. Drag and drop an image into the project bundle

  2. Localize images

  3. Select other languages

  4. An icon image can be seen in the localization folder of the corresponding image

  5. Replace ICONS in the. Lproj folder of the corresponding language with other ICONS with the same name

    Operate like any other language

  6. After completing step 5, go back to the project and click on the corresponding language. strings file to see the corresponding icon

  7. Use the icon name langueIcon as the key and NSLocalizedString to get the language string

  • The operation effect is as follows: 5.1

Localizing images requires multiple similar images. If multiple languages are used at a time, it is inevitable that the package size becomes larger. In this case, you can consider the method of obtaining images dynamically. This on-demand acquisition is more feasible in multiple languages

6 Localize Xib

6.1 Localizing Xib

  1. Vc to create xiB

  2. Localize xib file, note: select Base and nothing else

  • Otherwise, no corresponding key-value will be generated
  1. Check other languages

In contrast to other strings files, if you localize xiB or SB, the strings file in the corresponding language can be converted to a particular XIB style

You can choose to have other languages use strings files based on the Base XIB; Or each language could become a separate XIB file
However, it is not recommended to use the form of a separate XIB, although it can be used if different languages have different layouts

  1. Select Base String to automatically generate strings file content browsing system will generate content key value according to the Object ID of the child control (~ limited text control, such as: Label, Button, etc.) in the current XIB

  2. Change the corresponding value according to the language, the system will automatically obtain the CONTROL ID in the XIB and then match the system language for content assignment

  3. Modify the language Settings of Xcode and view the result

  • English

  • French

6.2 Preview localization in Interface Builder

In Interface Builder, you can preview the localization of the user Interface without running the application.

  1. In the project navigator, select the.storyboard or.xib file that you want to preview

  2. Choose View > Assistant Editor > Show Assistant Editor

  3. In the Assistant Editor jump bar, open the Assistant pop-up menu, scroll and select preview, then select.storyboard or.xib file from the submenu (~ If the preview of the application’s user interface is not shown in the Assistant Editor, select the window or view to preview in the icon or outline view ~)

  4. In the Assistant editor, select the localization you want to preview from the language pop-up menu in the lower right corner. A preview of the localization is displayed in the assistant editor. If the actual language is selected, strings that do not need to be localized or that need to be localized but are not currently localized are displayed in uppercase ~)

6.3 Adding a New Control to the XIB

  1. We found that after adding a new control, the corresponding strings file did not change automatically ⁉ ️

Note: Once strings of the corresponding Xib language is generated, any editing of Base Xib will not affect strings, even if a Label is deleted or added, and strings will not be changed synchronously

  1. Add it manually (~ certainly possible ~)
  • After obtaining the ObjectID of the corresponding Label, refer to the Label processing format that was added to the XIB before strings was generated and modify the strings files of the corresponding language as follows:

  • Running effect

6.3 Automatically updating strings Files

  1. Mode 1: UseibtoolGenerate a new.stringsFile (~ we will analyze how to use this later ~)
  • Xcode provides that for usibtoolUtility to generate strings file for Xibibtool XibController.xib --generate-strings-file ./XibController.strings
  • But theibtoolThe values in the translated key-value pair are displayed as the text filled in on the control on the XIB, which is generally not what we want. If we want to implement the update, we need to attach xibController.strings to the previous language folderfr.lprojXibcontroller. string = xibController. string = xibController. string = xibController. string = xibController. string = xibController. string = xibController. string = xibController. string = xibController. string = xibController. string
  1. Method 2: Use a script to automatically add a new key-value to the script and delete the key-value that no longer existsibtool
  • Logic is: Suppose we will have A translation file, add controls, we then perform A internationalization instruction to generate the file B, we take A and B, B in many out of the tail end of the keys to insert A file, will have A and B is not the key to delete (that is, the control to be deleted), so that we will be updated storyboard translation files

  • Following the logic above, we can use Script files to achieve this. Xcode’s Run Script also provides Script support, which allows us to execute the Script after Build

2.1 Creating the py Script

2.2 Select Target -> Build Phases -> New Run Script Phase and write the following commands in the shell

#! /bin/bash
python ${SRCROOT}/${TARGET_NAME}/RunScript/AutoGenStrings.py ${SRCROOT}/${TARGET_NAME}
Copy the code

2.3 You can also choose Run Script only when installing, so the script will not be used during compilation and will only be Run when you install

2.4 After a new control is added, the corresponding strings file will add the key-value pair of the new control, and the key-value pair of the deleted control will be commented out

The autogenstrings. py interpretation will be added later, and the reference script was originally just storyboard processing, which is extended to xiB

Localize the Storyboard

  • This operation is consistent with the Xib operation process. For details, see the Xib localization process

8 whatNSLocalizedString(key, comment)The use of the comment parameter in

The first argument is the name of the key and the second argument is the comment on the “key/value pair”, which is automatically added when genstrings generates the Localizable. Strings file

Under normal circumstances, the operation of language translation is not done by our programmers (of course, nb apes will take over the work), so how can we distribute the language localization strings file and work well according to the process?

8.1 Use directly in codeNSLocalizedStringDo imaginary localization implementation

  • So what happens here is that there’s no strings file locally, so useNSLocalizedStringReturn the key if the key does not exist
  • Therefore, during the development process, the interface displays the key value, which is recommendedThe advantage of English keys is that when the supported language is exceeded, English is used by default. Then using the English translation of the key just fits the bill

8.2 throughgenstringsWill use theNSLocalizedStringtheviewController.mFile to generate strings files corresponding to the locale

  • When all the.m files are usedNSLocalizedStringOnce it’s fixed, it’s ready to gogenstringsThe tool
  1. Start the terminal and access the project directory.
  2. The lproj folder will be placed in the root directory of the project by default. The directory name will apply to the language corresponding to the Localizable. Strings file.
mkdir zh-Hans.lproj
mkdir en.lproj
Copy the code
  • We recommend using Xcode to help us build it. See article # 1: Adding international languages to support. This way you can also save yourself the hassle of shorthand directory names and choose the international languages you want to support directly from Xcode

  • Select the language

  • Generated.lproj folder

  • If you don’t have the en.lproj folder, click main.storyboard and put English in the localize location of the file

  • The en. Lproj

  1. generateLocalizable.stringsfile
genstrings -o zh-Hans.lproj *.m
genstrings -o en.lproj *.m
genstrings -o ja.lproj *.m
Copy the code

-o < folder > to specify the directory to place the generated Localizable. Strings file. *.m, scan all.m files. Other supported files include. H,. Java, etc.

  • aftergenstrings -o zh-Hans.lproj *.mCommand after the correspondingzh-Hans.lprojToo many foldersLocalizable.stringsAnd the same with other things
  1. Generate Localizable. Strings file and drag it to the project, Xcode will automatically merge it into one file, and the generated content will follow the previous NSLocalizedString(@”home”, @” this is used to generate strings file, A comment on the corresponding key-value line that is used to prompt translators or apes for relevant prompts “).

  2. We then distribute the documents to translators (~ or your own hands ~)

Note:genstringsInstructions can only be traversal of files in this directory, but cannot implement recursive traversal. To implement recursive variables, use the following commandfind ./ -name *.m | xargs genstrings -o en.lprojThis is the shell composite instructionfind+xargs.find ./ -name *.mIt recurses all of them.mThe file is stored in an arraypipePassed to the next instruction, andxargsIt’s going to split the array one by one and give it to Genstrings to execute.

9 In-app setting language (~ fill after practice ~)

10 Specify the language bundle to get the localized string.

  • Added macro usage examples
#define NSLocalizedString(key, comment) \
	    [NSBundle.mainBundle localizedStringForKey:(key) value:@"" table:nil]
#define NSLocalizedStringFromTable(key, tbl, comment) \
	    [NSBundle.mainBundle localizedStringForKey:(key) value:@"" table:(tbl)]
#define NSLocalizedStringFromTableInBundle(key, tbl, bundle, comment) \
	    [bundle localizedStringForKey:(key) value:@"" table:(tbl)]
#define NSLocalizedStringWithDefaultValue(key, tbl, bundle, val, comment) \
	    [bundle localizedStringForKey:(key) value:(val) table:(tbl)]
Copy the code

11 Start map localization (~ fill ~ after practice)

12 Optimization (~ fill after practice ~)

Demo

LanguageLocalizationDemo – used in points 1-7

Use LocalizationGenStringsDemo – 8 PM

Unfinished ~

REF

  • Internationalization – Apple Developer

  • Internationalization – Apple Developer New Localization Workflows in Xcode 10 – WWDC 2018 – Videos – Apple Developer

  • Test your internationalization application

  • IOS Internationalization – Storyboard translation autoincrement via scripting – Eastern Log – Blog garden


By Jacob_LJ, Nuggets writer

PS: Unless otherwise stated, all articles are original works, copyright belongs to the author, reprint need to contact the author to obtain authorization, and indicate the source, all rewards belong to myself!