directory
An overview of
Internationalization of various resources
1. The text
Picture 2.
3.nib
4. Other resources
Internationalization of a specific module/function
1. The APP icon
2. Application name and permission prompt
3. LaunchScreen
4. App adjusts the internationalization of system resource pages
5. Internationalization of server data content
Change the language in app
1. Language change scheme
2. Migration of old projects without internationalization
An overview of
The essence of internationalization is to provide a single resource (text, images, audio and video, etc.) for each language. The term localization refers to the internationalization of a single language: the combination of multiple languages
For every new language in Localizations, Xcode will prompt us to generate the corresponding file, and then generate the corresponding folder.
IOS provides a quick internationalization solution for these files. For string resource files generate string files for the appropriate language and put them in the corresponding folder, whereas XIB and StoryBoard can choose the entire file and string resources. Specific plans will be discussed later.
If you forget to add a specific language File for a resource, or if you add a subsequent resource File, you can do so using the Localize button in the File Inspector for that resource File.
Localizable. Strings and InfoPlist. Strings are common in internationalization scenarios.
- Localizable. Strings This is a method that reads strings in multiple languages
NSLocalizedString
File that will be loaded by default. If the file name is specified, useNSLocalizedStringFromTable
Select table from table - InfoPlist.strings
info.plist
String internationalization file, the system read by default, the name is fixed
Internationalization of various resources
1. The text
A string resource file with multiple languages added is in an expandable state, with child copies of the corresponding language. We just put the text in the corresponding language in the copy.
The format of the string file is “key” = “value”; The author found that key = “value”; There will also be no problem (but no Spaces without double quotation marks will not be recognized), such as the localization of the application name:
Be covered
Use NSLocalizedString(key, comment) to read the string. The second argument, comment, can be nil, an empty string, or a comment on the key.
Take a look at the implementation of this method
#define NSLocalizedString(key, comment) \
[NSBundle.mainBundle localizedStringForKey:(key) value:@"" table:nil]
...
/* Method for retrieving localized strings. */
- (NSString *)localizedStringForKey:(NSString *)key value:(nullable NSString *)value table:(nullable NSString *)tableName NS_FORMAT_ARGUMENT(1);
Copy the code
LocalizedStringForKey: value: the table: it is NSBundle object method, so, you can load a different package name and a string resource list of strings. Related macros are also provided
#define NSLocalizedStringFromTable(key, tbl, comment) \
[NSBundle.mainBundle localizedStringForKey:(key) value:@"" table:(tbl)]
#define NSLocalizedStringFromTableInBundle(key, tbl, bundle, comment) \
[bundle localizedStringForKey:(key) value:@"" table:(tbl)]
Copy the code
Important: The key is returned when the corresponding language strings or value is not found. If you use English content as the key, you don’t even need to maintain English localization.
Picture 2.
After Xcode5, image Assets (assets.xcassets) no longer support internationalization. The mode of individual image resources is still available, which is used in the same way as strings. Drag the image you want to internationalize into the project, select the file monitor, click Localize and select multiple languages to generate an expandable state like a string resource. To configure pictures in different languages, go to the language directory for replacement.
The solution supports Interface Builder niB resource internationalization (of course Localizable Strings are obviously just Strings) and + imageNamed: loading internationalization.
There is also an approach that is suitable only for pure code and does not support NIB. Internationalize the name of the image as a string and then use + imageNamed: load.
In addition, for the loading mode of +imageWithContentsOfFile:, the corresponding loading path can be modified according to the language through classification.
PS: The internationalization of images brings multiple copies. If there are many specific localization languages to be done in the internationalization, it is bound to cause a sharp increase in packages. So if you can avoid it, avoid it.
3. Nib files (XIB and StoryBoard)
There are two ways to internationalize niB files:
- Only string resources (Localizable Strings)
- Whole NIB file (Interface Builder CocoaTouch XIB/StoryBoard)
Nib file has a big hole, draw focus
Individual localized NIB changes are not synchronized, and NIB changes are not synchronized to string resources
That is to say, the first solution requires another page for every language added, which is a huge amount of extra work for localizing multiple languages. In the second case, you have to copy the new string yourself.
If you want to automate the update synchronization process, of course, strings are also convenient. There are two advantages to internationalizing an entire NIB file over a string resource
- The picture
- Different locales have different layouts
In general, it does not change the layout according to the different localization languages. Arab countries also change the text direction. This feature view is built-in, and can be changed globally.
[UIView appearance].semanticContentAttribute = UISemanticContentAttributeForceRightToLeft;
Copy the code
Image resources in NIB can also be easily solved by code. In summary, THE author suggests only Localizable Strings for NIB files.
So, is it any surprise that the above image scheme was selected to support niB and now it is not 🤣? Is it a surprise?
Let’s move on to niB’s new string synchronization that requires internationalization.
Xcode provides us with the ibTool to generate strings files for niB
ibtool FirstViewController.xib --generate-strings-file lanuchScreen.strings
ibtool Main.storyboard --generate-strings-file storyBoard.strings
Copy the code
But the strings file generated by ibTool is strings from the BaseStoryboard (default language strings) and replaces our original (and even translated) strings. It’s better to do this yourself with a Script, then Run the Script in Xcode, and build it when you update it. In the final Demo, add the Run Script to Target->Build Phases->New Run Script Phase, and write the following instructions in the shell
python ${SRCROOT}/${TARGET_NAME}/RunScript/AutoGenStrings.py ${SRCROOT}/${TARGET_NAME}
Copy the code
4. Other resources
Other resources (JSON, audio and video, compressed packages, etc.) are internationalized in the same way as image resources. You can read the main Bundle when you read it, and iOS automatically cuts it for different locales.
Full disclosure: Future in-app switching languages will take advantage of this feature of the main Bundle.
5. Internationalization of server data content
For internationalization of this part of the content, the following two options can be considered:
- The server does not care about the current user’s localization language and returns all localized content that is adapted, with the client controlling the display itself
- The server retrieves localized information for the current user and returns localized content
The first is suitable for less localized languages, such as only English and Chinese. In the second case, the server needs to modify a lot because it is highly dependent on configuration information.
If the first method is used, some commonly used error messages or other business success information can be sorted into a specific code and directly parsed by the client, reducing the amount of information transfer (although it is still much larger than a single localization).
If you use the second option, you can put the current user’s localization information in the request header, which makes it much easier for the server.
Internationalization of a specific module/function
1. The APP icon
In addition to the dynamic icon method, there is no way to dynamically modify the icon. This method is mostly used for APP festival activities. And actually no one has done internationalization of this, by the way.
2. Application name and permission prompt
Internationalization of application name and permission hints is info.plist-dependent internationalization. Different localization files can be placed in different key-value pairs.
3. LaunchScreen
The startup diagram is described in the Adding Assets section of Xcode Overview
Because the launch screen is shown before your app is running, you can only use a single root view of type UIView or UIViewController.
This means that the display of the startup screen occurs before the entrance of the main function, which means that we cannot change the startup diagram dynamically. In addition, the following two approaches to internationalization of NIB are also ineffective.
The joke here is that even with static internationalization, the following two conditions do not switch
- When the system switches languages
- Restart the system
It will only be switched when the app is reinstalled so the internationalization significance of making a startup image is limited.
I also see some people say that they make a LaunchScreenController as the launch screen, but in this case, the app will be black for a period of time, which is not the desired effect.
4. Internationalize the page of the app system
As for calling system resources, camera, album, address book, etc., the modification language in APP has not found a way to refresh. If you have the method, please inform the landlord, thank you very much.
The AppleLanguages in the main function that were set before the AppDelegate returned are valid only when the app restarts.
So, the current solution is to implement these pages all by themselves. In addition, the internationalized text of the navigation button is not loaded in the main bundle. The app will also customize the button, which is not a pain point.
If there are other, welcome to add.
Change the language in app
1. Language change scheme
The language of the APP is changing with the language setting of the system, which is the most basic international requirement. More often, we hope to be able to change the language inside the app.
The loading of resources (storyboards, images, strings) in the APP is basically done on nsbundle.mainbundle () (self-built private libraries or third-party libraries may internationalize themselves by placing internationalized string resources in their own bundles, such as MJRefresh). After the language switch, we simply replace the bundle loaded by the corresponding resource with the bundle of the current language. Replace this with the main code for string resource loading:
id value = language ? [NSBundle bundleWithPath:[[NSBundle mainBundle] pathForResource:@"zh-Hans" ofType:@"lproj"]] : nil; objc_setAssociatedObject([NSBundle mainBundle], &kBundleKey, value, OBJC_ASSOCIATION_RETAIN_NONATOMIC); ... - (NSString *)localizedStringForKey:(NSString *)key value:(NSString *)value table:(NSString *)tableName { NSBundle *bundle = objc_getAssociatedObject(self, &kBundleKey);if (bundle) {
return [bundle localizedStringForKey:key value:value table:tableName];
} else {
return[super localizedStringForKey:key value:value table:tableName]; }}Copy the code
Image loading in the corresponding NIB file and text in the UITextView are also required
If the project is pure code, meaning that internationalization does not involve NIB files, then this implementation is not necessary. Save the current language tag for yourself, change it when switching, and make a judgment call.
If you want to follow the Language of the system during the first installation, you can read an array of languages from NSUserDefault after the application starts. The first element of the array is the Primary Language, the current Language of the system. The last part of these language strings is the locale, which varies by locale, so be careful when judging from this list later.
NSArray *array = [[NSUserDefaults standardUserDefaults] arrayForKey:@"AppleLanguages"];
Copy the code
Either way, switching languages requires refreshing the view, which is unavoidable. So, how do you gracefully refresh the UI
- The idea is that when switching languages, NSNotification is sent, and all UI controls listen for notifications and then refresh the UI when appropriate. In fact, there are a lot of things to do, either through the Base class to implement, or through the Runtime implementation, Button, Label, TextField, etc., need a unified update mechanism, may not be the easiest way.
- The solution for wechat switching is to refresh the rootViewController of keyWindow and jump to the Settings page.
This idea has a more detailed article, directly read: in iOS App elegant dynamic language switch
2. Migration of old projects without internationalization
The international migration of older projects also involves all of the issues mentioned above. But none of the above is the main problem. The main problem is all the text scattered in the code that needs to be internationalized. It’s not realistic to pick them out one by one. Xcode provides a utility called Genstrings, which, like IBTool, exports string resource files. It’s just that ibtool works with NIB files and Genstrings works with source files. Support C, Objective-C, Swift, Java and other language files, the following official description:
The
genstrings
tool can parse C, Objective-C, and Java code files with the.c
,.m
, or.java
filename extensions.
However, there is still a lot of work to be done. Take a look at the official description:
If you wrote your code using the Core Foundation and Foundation macros, the simplest way to create your strings files is using the
genstrings
command-line tool. You can use this tool to generate a new set of strings files or update a set of existing files based on your source code.
In other words, this script works only if you use the NSLocalizedString series of macros, one by one, to replace the string for the macro to read. However, it is logical to think about it, since it is up to the developer to decide which string should be internationalized. Do it yourself using Find Navigator.
How to use
Swift: // Localizable. Strings: // Localizable. Strings: // Localizable. Strings: // Localizable. Strings: // Localizable. Append genstrings-a -o en.lproj *.swift
Copy the code
Other parameters can be viewed using the man genstrings command without further elaboration. This command line tool also suffers from the ibTool, full output. Therefore, be careful not to overwrite what has already been translated when using it.
Take a look at the effect:
In addition, this command can only parse one file at a time, simply writing a recursive script:
#! /bin/bash
function getdir() {for element in `ls The $1`
do
dir_or_file=The $1"/"$element
if [ -d $dir_or_file ]
then
getdir $dir_or_file
else
echo $dir_or_file
suffix="${dir_or_file##*.}"
if [ "$suffix"x = "swift"x ]||[ "$suffix"x = "m"x ]||[ "$suffix"x = "mm"x ];
then
genstrings -a -o en.lproj $dir_or_file
fi
fi
done
}
root_dir=". /"
getdir $root_dir
Copy the code
This is the end of iOS internationalization. If you have any questions, please check out the demo or leave a message. Finally attached: demo address
Reference article: Internationalization and Localization Guide Using the genstrings Tool to Create Strings Files IOS internationalization — Storyboard translation customization via scripting iOS internationalization gracefully dynamically switches languages within the iOS App
The author and a friend did taobao coupons public number, shopping coupons to save money, help pay attention to it.