This repository contains the i18nGen command line tool that takes language/localization yaml files as input and automatically generates Swift and Kotlin code containing the localized strings.
This tool is compatible with lyaml files generated by Transifex, and it was originally developed for HubSpot's mobile apps.
Watch the presentation on YouTube.
i18nGen requires Swift 5 and it was tested on macOS 10.14 and Ubuntu 18.04
- Clone this repository:
$ git clone https://github.com/fabio914/mobile-i18n.git- Go to the mobile-i18n-generator folder:
$ cd mobile-i18n- Run the install script:
$ ./install.shor
$ ./installLinux.sh$ i18nGen <main language YAML file> [additional language YAML files ...] [output options] [warning options]Examples (Swift):
$ i18nGen en.lyaml de.lyaml es.lyaml fr.lyaml ja.lyaml pt-br.lyaml -swiftOutputs a Swift dictionary, without warnings:
$ i18nGen en.lyaml de.lyaml es.lyaml fr.lyaml ja.lyaml pt-br.lyaml -swift-dictionary -wAll warnings:
$ i18nGen en.lyaml de.lyaml es.lyaml fr.lyaml ja.lyaml pt-br.lyaml -swift -WallExamples (Kotlin):
$ i18nGen en.lyaml de.lyaml es.lyaml fr.lyaml ja.lyaml pt-br.lyaml -kotlin com.organization.localizationOutputs Kotlin code without static strings:
$ i18nGen en.lyaml de.lyaml es.lyaml fr.lyaml ja.lyaml pt-br.lyaml -kotlin-filtered com.organization.localizationAll warnings:
$ i18nGen en.lyaml de.lyaml es.lyaml fr.lyaml ja.lyaml pt-br.lyaml -kotlin com.organization.localization -WallA Localization.swift (or Localization.kt) file will be generated if i18nGen succeeds.
- Add an
en.lyamlfile to your project/target (DO NOT add this file, or any other.lyamlfile, to the Copy Bundle Resources phase):
en:
hello:
title: "Hello"
message: "Hello {{ name }}!"
done: "Done"- Add a new Build Rule to your XCode project/target:
cd ${DERIVED_FILE_DIR}
i18nGen ${INPUT_FILE_PATH} `find ${INPUT_FILE_DIR} -name "*.lyaml" | grep -v en.lyaml | tr '\n' ' '` -swift- Add the
en.lyamlfile to the Compile Sources phase:
- Add additional language files (DO NOT add these
.lyamlfiles to the Copy Bundle Resources or Compile Sources phase):
es:
hello:
title: "Hola"
message: "¡Hola {{ name }}!"
done: "Hecho"pt-br:
hello:
title: "Olá"
message: "Olá {{ name }}!"
done: "Feito"Remember to keep these .lyaml files all on the same directory in your target/project.
XCode will only track changes to the en.lyaml file. Remember to clean the project (including your project's derived data) by pressing ⌥⇧⌘K when modifying any of the other .lyaml files or updating the i18nGen tool!
-
Build the project.
-
Your strings will be defined under
LocalizedStringsand you can access them via thelocalizedStringsinstance:
let namespace = localizedStrings.hello
let alert = UIAlertController(title: namespace.title, message: namespace.message(name: "John"), preferredStyle: .alert)
alert.addAction(UIAlertAction(title: namespace.done, style: .default, handler: { _ in }))
present(alert, animated: true, completion: nil)- Result:
Usage with XCodeGen (iOS)
- Add an
en.lyamlfile to your target:
en:
hello:
title: "Hello"
message: "Hello {{ name }}!"
done: "Done"- Add your
en.lyamlfile to yourproject.yml's target sources:
sources:
# ...
- path: "path/to/folder/en.lyaml"
buildPhase: sources
createIntermediateGroups: true- Add a new Build Rule to your
project.yml's target:
buildRules:
# ...
- name: Localize
filePattern: "*/en.lyaml"
script: |
cd ${DERIVED_FILE_DIR}
i18nGen ${INPUT_FILE_PATH} `find ${INPUT_FILE_DIR} -name "*.lyaml" | grep -v en.lyaml | tr '\n' ' '` -swift
outputFiles:
- $(DERIVED_FILE_DIR)/Localization.swift- Add additional language files (inside the same folder as your
en.lyaml):
es:
hello:
title: "Hola"
message: "¡Hola {{ name }}!"
done: "Hecho"pt-br:
hello:
title: "Olá"
message: "Olá {{ name }}!"
done: "Feito"- Add the extra language files to your
project.yml(optional):
sources:
# ...
- path: "path/to/folder"
buildPhase: none
createIntermediateGroups: true
excludes:
- "en.lyaml"- Regenerate your XCode project:
$ xcodegen generate-
Build your target.
-
Your strings will be defined under
LocalizedStringsand you can access them via thelocalizedStringsinstance:
let namespace = localizedStrings.hello
let alert = UIAlertController(title: namespace.title, message: namespace.message(name: "John"), preferredStyle: .alert)
alert.addAction(UIAlertAction(title: namespace.done, style: .default, handler: { _ in }))
present(alert, animated: true, completion: nil)- Result:
PS: Our gradle plugin needs to be updated to version 2.0.
- Add these rules to your root-level
build.gradlefile:
apply plugin: 'com.i18n.community.localization'
buildscript {
// ...
repositories {
// ...
jcenter()
}
dependencies {
// ...
classpath "com.i18n.community.localization:GradlePlugin:1.0.+"
}
}-
Create a
langdirectory inside your module's root; -
Create an
en.lyamlfile inside thatlangdirectory:
en:
hello:
title: "Hello"
message: "Hello {{ name }}!"
done: "Done"- Create additional language files
es:
hello:
title: "Hola"
message: "¡Hola {{ name }}!"
done: "Hecho"pt-br:
hello:
title: "Olá"
message: "Olá {{ name }}!"
done: "Feito"-
Build the project.
-
Your strings will be defined under
LocalizedStrings:
val namespace = LocalizedStrings.hello
AlertDialog.Builder(this)
.setTitle(namespace.title)
.setMessage(namespace.message(name = "John"))
.setPositiveButton(namespace.done) { _, _ -> }
.create()
.show()- Result:








