Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Xamarin iOS localization using .NET

I'm trying to use .NET localization in a portable class library for a Xamarin iOS/Android project. I've followed the steps at:

How to use localization in C#

And have code which looks as follows:

string sText = strings.enter_movie_name;
Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo("fr");
sText = strings.enter_movie_name;
lblEnterMovieName.Text = sText;

I've also tried:

ResourceManager resman = new ResourceManager(typeof(MyApplication.strings));
string sText = resman.GetString("enter_movie_name", new CultureInfo("fr"));

I've created strings.resx with enter_movie_name equal to "Enter movie name:" and strings.fr.resx equal to "Entre la movie name:"

However, sText always ends up as "Enter movie name:". I can't seem to get the "Entre la movie name:" version out.

I also saw the post at Cross-platform Localization but couldn't work it out. I also don't want to use the iOS specific version at Localization on Xamarin.iOS as I'd like to be able to get at my strings from a platform independent library.

Can anyone point out where I'm going wrong?

like image 916
Dave Avatar asked Dec 13 '13 14:12

Dave


People also ask

Can you build an iOS app in C#?

Xamarin lets you develop fully native Mac apps in C# and . NET using the very same macOS APIs as you would for Objective-C or Swift projects. You can either create your user interfaces directly in C# code, or, thanks to Xamarin's direct integration with Xcode, you can use Xcode's Interface Builder.

How do you implement localization in iOS Swift?

Click on iOS->App/Single View App->Next. Name your project and select the language as Swift. Select a desired location and click on Create. To start with Localization, click on your Project Name -> go to Info Tab -> Under Localizations, click on the '+' button.


1 Answers

I've created a bit of an ugly solution, but it works. What I've done is made a folder called 'strings' in my Portable Class Library (PCL) and inside that created files called:

  • strings.resx
  • strings_fr.resx
  • strings_ja_JP.resx

I've set all of these as Embedded Resource with custom tool as ResXFileCodeGenerator. This means I have a separate resource DLL for each language.

In iOS I can then get the locale by calling:

string sLocale = NSLocale.CurrentLocale.LocaleIdentifier;

I would guess there's an Android equivalent using Locale but I don't know what it is.

This gives me a string like "ja_JP" or "fr_FR" or "en_GB" (note they're underscores, not dashes). I then use this with the following static class I created to retrieve an appropriate resource manager and get the string from it.

If given a locale aa_BB it first looks for strings_aa_BB, then for strings_aa, then for strings.

public static class Localise
{
    private const string STRINGS_ROOT = "MyPCL.strings.strings";

    public static string GetString(string sID, string sLocale)
    {
        string sResource = STRINGS_ROOT + "_" + sLocale;
        Type type = Type.GetType(sResource);
        if (type == null)
        {
            if (sLocale.Length > 2) {
                sResource = STRINGS_ROOT + "_" + sLocale.Substring(0, 2); // Use first two letters of region code
                type = Type.GetType(sResource);
            }
        }
        if (type == null) {
            sResource = STRINGS_ROOT;
            type = Type.GetType(sResource);
            if (type == null)
            {
                System.Diagnostics.Debug.WriteLine("No strings resource file when looking for " + sID + " in " + sLocale);
                return null; // This shouldn't ever happen in theory
            }
        }
        ResourceManager resman = new ResourceManager(type);
        return resman.GetString(sID);
    }
}

An example of how this would be used (referring to the above code) would be:

string sText = Localise.GetString("enter_movie_name", sLocale);
lblEnterMovieName.Text = sText;

A significant downside of this is that all views will need to have their text set programatically, but does have the upside that the translations can be done once and then reused on many platforms. They also remain separate from the main code in their own DLLs and therefore can be recompiled individually if necessary.

like image 156
Dave Avatar answered Sep 22 '22 10:09

Dave