This guide explains how to implement multilanguage support in your Smartface applications.
Smartface supports the i18n localization system. “i18n.js” is available in the i18n folder. Some language files added by default. You can also add your own language with the following steps:
Create a copy of one of the language .js files in the i18n folder.
Rename and edit the .js file accordingly. (example.js in this case)
In the next step, you need to "require" that file in the i18n.js file.
You can add two-letter ISO 639-1 standard language codes after adding the ‘case’ command in the Language section.
If you want to change the app language, go to “i18n.js" script file and edit the "SMF.i18n.switchLanguage();" function. For example; add “fi” for Finnish. To use the device locale as default, you can leave the string as “Device.language”.
"global.SMF.i18n.changeLanguageTo()" is used to change language in runtime then Application.restart() must be triggered as following function.
global.SMF.i18n.currentLang() returns the current language code of the app is being run.
global.SMF.i18n.defaultLang() returns the default language code of the app.
Few languages such as Arabic, Hebrew, or Persian are written from Right to Left. To handle them, views can be converted to RTL theme within Smartface.
When your app calls checkPermission(permission), the system shows a standard dialog box to the user. Your app cannot configure or alter that dialog box. If you need to provide any information or explanation to the user, you should do that before you call checkPermission(permission), as described in Explain why the app needs permissions.
"lang" array in the “i18n.js” is used for language bindings with the keys. Let's add two labels into our project to get a specific text from the lang array.
TypeScript code blocks include examples of how to implement, override and components within the theme. You can create page with the UI Editor to make your page compatible with theming and then you can implement themable components programmatically. Once the page is created with the UI Editor, it generates a class under scripts/generated/pages
. You can then extend that class with the following TypeScript classes.
import PageSampleDesign from 'generated/pages/pageSample';import FlexLayout = require('sf-core/ui/flexlayout');import Application = require('sf-core/application');import System = require('sf-core/device/system');import Label = require('sf-core/ui/label');//You should create new Page from UI-Editor and extend with it.export default class Sample extends PageSampleDesign {myLabel: Label;constructor() {super();// Overrides super.onShow methodthis.onShow = onShow.bind(this, this.onShow.bind(this));// Overrides super.onLoad methodthis.onLoad = onLoad.bind(this, this.onLoad.bind(this));this.layout.flexDirection = FlexLayout.FlexDirection.COLUMN;this.layout.justifyContent = FlexLayout.JustifyContent.CENTER;this.layout.alignItems = FlexLayout.AlignItems.CENTER;}}/*** @event onShow* This event is called when a page appears on the screen (everytime).* @param {function} superOnShow super onShow function* @param {Object} parameters passed from Router.go function*/function onShow(superOnShow: () => void) {const { headerBar } = System.OS === "Android" ? this : this.parentController;superOnShow();Application.statusBar.visible = true;headerBar.visible = true;}/*** @event onLoad* This event is called once when page is created.* @param {function} superOnLoad super onLoad function*/function onLoad(superOnLoad: () => void) {superOnLoad();this.myLabel = new Label({text: lang['cancel']});this.layout.addChild(this.myLabel, "myLabel", ".sf-label", {height: 60,width: 120,backgroundColor: "#00A1F1",textAlignment: "MIDCENTER"});}
const Page = require("sf-core/ui/page");const extend = require("js-base/core/extend");const Color = require('sf-core/ui/color');const FlexLayout = require('sf-core/ui/flexlayout');const Label = require('sf-core/ui/label');const TextAlignment = require('sf-core/ui/textalignment');var Page1 = extend(Page)(function(_super) {_super(this, {onShow: function(params) {Application.statusBar.visible = false;this.headerBar.visible = false;}});this.layout.flexDirection = FlexLayout.FlexDirection.ROW;this.layout.justifyContent = FlexLayout.JustifyContent.CENTER;this.layout.alignItems = FlexLayout.AlignItems.CENTER;var myLabel = new Label({width: 120,height: 60,backgroundColor: Color.create("#00A1F1"),text: lang['cancel'],textAlignment: TextAlignment.MIDCENTER});this.layout.addChild(myLabel);});module.exports = Page1;
Both Android and iOS has their own dialog structure. For native experience, Smartface advises to use what platform offers.
Texts on Android can be changed by the developer, so you can use common localization methods to customize them.
For iOS, Permission and some native dialogs cannot be customized on runtime, therefore developer needs to define what texts to use on Info.plist.
Create a folder called Localization inside of config/iOS.
Create a folder called e.g. en.lproj and a new folder for each language you want to include. Languages should be alpha2 coded.
Inside of each folder, create a new file called InfoPlist.strings and populate the file like example is shown at below:
"NSLocationWhenInUseUsageDescription" = "Location access is required";"NSPhotoLibraryUsageDescription" = "Gallery access is required";"NSCameraUsageDescription" = "Camera access is required";
"NSLocationWhenInUseUsageDescription" = "L'accès à l'emplacement est requis";"NSPhotoLibraryUsageDescription" = "L'accès à la galerie est obligatoire";"NSCameraUsageDescription" = "L'accès à la caméra est requis";
You can check what keys can be customized on this Apple documentation
Don't forget to add relevant keys in Info.plist file in xml format as well. The language in the xml module should be in your default language, for failsafe approach.
Also refer: AboutInformationPropertyListFiles