Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cross-platform Localization

With Xamarin Android, it possible to create localized strings for multi-language apps, as is shown in their Android documentation:

http://docs.xamarin.com/guides/android/application_fundamentals/resources_in_android/part_5_-_application_localization_and_string_resources

However, I have various try/catch blocks in my Model which send error messages back as strings. Ideally I'd like to keep the Model and Controller parts of my solution entirely cross platform but I can't see any way to effectively localize the messages without passing a very platform specific Android Context to the Model.

Does anyone have ideas about how this can be achieved?

like image 492
Dave W Avatar asked Dec 26 '22 02:12

Dave W


1 Answers

I'm using .net resource files instead of the Android ones. They give me access to the strings from code, wherever it is.

The only thing I can't do automatically is reference those strings from layouts. To deal with that I've written a quick utility which parses the resx file and creates an Android resource file with the same values. It gets run before the Android project builds so all the strings are in place when it does.

Disclaimer: I haven't actually tested this with multiple languages yet.

This is the code for the utility:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml;

namespace StringThing
{
    class Program
    {
        static void Main(string[] args)
        {
            string sourceFile = args[0];
            string targetFile = args[1];

            Dictionary<string, string> strings = LoadDotNetStrings(sourceFile);
            WriteToTarget(targetFile, strings);
        }

        static Dictionary<string, string> LoadDotNetStrings(string file)
        {
            var result = new Dictionary<string, string>();

            XmlDocument doc = new XmlDocument();
            doc.Load(file);

            XmlNodeList nodes = doc.SelectNodes("//data");

            foreach (XmlNode node in nodes)
            {
                string name = node.Attributes["name"].Value;
                string value = node.ChildNodes[1].InnerText;
                result.Add(name, value);
            }

            return result;
        }

        static void WriteToTarget(string targetFile, Dictionary<string, string> strings)
        {
            StringBuilder bob = new StringBuilder();

            bob.AppendLine("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
            bob.AppendLine("<resources>");

            foreach (string key in strings.Keys)
            {
                bob.Append("    ");
                bob.AppendLine(string.Format("<string name=\"{0}\">{1}</string>", key, strings[key]));
            }

            bob.AppendLine("</resources>");

            System.IO.File.WriteAllText(targetFile, bob.ToString());
        }
    }
}
like image 122
Martynnw Avatar answered Jan 11 '23 23:01

Martynnw