Tuesday 24 November 2015

Code internationalisation and operation declutter

An important aspect in any application is the ability to use different languages within an app and FTrack is no different.

The current iOS and Android versions have platform specific language files which doesn't transfer over well to Xamarin Forms. Thankfully, it's easy enough to internationalise a forms application and make use of how Windows Phone does things (with the multilingual toolkit).

For the basics of internationalising a forms app : https://developer.xamarin.com/guides/cross-platform/xamarin-forms/localization/

For using the multilingual tool : http://blog.giovannimodica.com/post/internationalization-of-a-cross-platform-application

The issue though comes with there being around 2300 different strings and there isn't a chance that I will copy and paste each over to the resx file. The solution was simple.

The resx XML looks like this

<data name="foo" xml:space="preserve">
   <value>some text</value>
</data>

Rather than have to re-write anything, a small piece of code reads the old Apple en.lproj file, parses the code and spews out the XML which you then add directly after the last <resheader> and before the closing </root> (removing anything else between it).

A couple of gotchas though - you can't have / or . in the name property. This is a pain as many text lookups are of the form uipage.textproperty

The code to do the conversion is this

using System;
using System.IO;
using System.Collections.Generic;

namespace MessageConverter
{
    /*
     <data name="Done" xml:space="preserve">
        <value>Done</value>
    </data>
    */

    class MainClass
    {
        public static void Main(string[] args)
        {
            var dataList = new List<string>();

            var fileLines = File.ReadAllLines("Localizable.strings");
            foreach (var f in fileLines)
            {
                var lines = f.Split('=');
                if (lines.Length > 1)
                {
                    dataList.Add(string.Format("<data name=\"{0}\" xml:space=\"preserve\">", lines[0].Replace("\"", "")));
                    dataList.Add(string.Format("<value>{0}<\\value>", lines[1].Replace("\"", "").Replace(";", "").Replace(".","_").Replace("/", "_");
                    dataList.Add(string.Format("</data>"));
                }
            }
            File.WriteAllLines("newtext.resx", dataList);
        }
    }
}

Okay, there is no error trapping in there and the file has to be in the same directory as the binary, but hey, it works and means I don't have to convert everything by hand!

Using the new strings in the app

Thankfully, when I wrote FTrack2 I did it in such a way that I use a string lookup and then add the string into the UI directly viz

myUILabel.Text = Strings.GetString("myText");

A quick search and replace and Strings.GetString becomes LangResources.myText

Okay, there is a bit more to it than that, but still covers much of the grunt work

Operation Declutter

By far the biggest job is the moving over of the UI. There isn't an automated way to generate XAML from a XIB file, so much of the UI has to be written by hand. The way iOS works is to create a designer file as well as the standard C# file associated with the xib. This includes a lot of stuff in there which is very specific to iOS - all of which has to be removed. There is no easy way to do this other than go through each source file and remove it.

There is a big advantage in this - I can go through the code base and rip out the common methods to create some nice clean generic ones which should help with the performance. Let's see what it yields!

No comments:

Post a Comment