Easy and cross-platform localization (Xamarin & .NET)


Sooner or later we all need to localize an app in multiple languages. Each platform provides its own way of localizing strings and you may wonder how to share locale files between them.

If you are a .NET dev, Resx is probably the first thing crossing your mind, and that´s totally fine for Visual Studio. It can be implemented on Xamarin as well but you´ll find yourself (and potentially your client) editing xml files with the following format:

<data name="Key" xml:space="preserve">
    <value>KeyValue</value>
    <comment>Some comments</comment>
</data>

At least at the time of this writting Xamarin does not provide a Resx editor. Besides, you need to write code for manually loading the correct language, based normally on the current system culture. Xamarin has a nice tutorial on how to do it. You´ll find even iOS, Android and win phone concrete implementations and a bunch of useful details. They also explain how to automatically bind translations in XAML creating a IMarkupExtension class.

The problem is:

  • I don´t want to repeat all that process in every project, or even copy-paste across projects and platforms.
  • I just want a library to do it for me
  • I don´t like/want Resx files and I don´t want to have a client editing them

Hello I18N-Portable

I love simplicity and that´s why I created a lightweight utility for this matter. My idea was based on two concepts:

  • Simpler locale files (similar to java .properties format)
  • Straightforward setup and initialization

Install

I18N-Portable is a nuget package

Locales

A locale is just a [locale].txt file with key=value pairs. You place these files on a PCL project once, under a directory called “Locales”. They will be shared across platforms:

# this is a comment
key1 = one
key2 = two
key3 = translation with \nmultiple \nlines

Setup

I18N.Current
    .SetFallbackLocale("en")
    .Init(GetType().GetTypeInfo().Assembly);

That´s all you need. Simple enough?

You put this line at your PCL code, normally in any method executed during app initialization.

What did just happen?

The Init() method tells I18N-Portable which assembly is hosting the locales. Now the library figures out the current system culture and tries to load a matching locale. If you didn´t provide a locale for the current culture, it will fallback to english (“en.txt”).

From now on you can get any translation with a string method extension from anywhere in your app PCL and/or platform projects:

var translation = "key1".Translate(); // one

Can I use this with my awesome Mvvm framework?

Sure. You can bind any text view to a particular key, from XAML (Xamarin.Forms, UWP, etc) and classic Android/iOS if your Mvvm framework implements bindings:

XAML:

<Button Content="{Binding [key]}" />

Xamarin.Forms XAML:

<Button Text="{Binding [key]}" />

Android with MvvmCross:

<TextView local:MvxBind="Text [key]" />

iOS with MvvmCross:

bindingSet.Bind(view).To("[key]");

To make this work, a simple indexer is needed in your ViewModel (I usually do this in a BaseViewModel once):

public string this[string key] => key.Translate();

More handy stuff and details are available at the github repo

Cheers!

Related Posts

A simple page-indicator for your android view-pager

It only takes a little xml and five minutes of your time

Large file downloads on Windows 10 mobile

With progress feedback

UWP mobile side loading

The key details

SQLite.NET > async VS sync

Or how we love to complicate things

Making iOS forms usable

Prevent user frustration by implementing good practices with Xamarin.iOS

Going back to the nineties

Or how to make a blog without a database