How to convert Android XML to iOS .strings using Localazy

How to convert Android XML to iOS .strings using Localazy

Localizable file format conversion is not an easy task, considering the required transformation, the different support for plural forms, and the many other challenges of converting one file to another format.

Fortunately, Localazy comes with the Format Conversions feature and vast support of formats and integrations you can utilize by downloading our multiplatform command-line interface (CLI) tool.

🔖 Why Android XML to iOS .strings?

Android and iOS are, without a doubt, the most used mobile operating systems, both with billions of users and with the largest app stores in the global market.

Android and iOS app development differs, but you can preserve the content. So, you can develop an Android app first, and as long as you keep the strings and the remaining content (audio, images, video, etc.) external, you'll be able to reuse it to develop an iOS version of the app.

This approach allows you not to have to do everything from scratch again and save your time.

❓ What are localizable file format conversions?

To localize a project, we need to keep everything the user sees external to ensure that whenever we need to adapt the project to different areas/regions/countries, we won't have to fiddle with the code every time we want to add a new locale.

Read our guide on How to prepare your app for i18n & l10n

The text is how we mainly communicate with the user, and so we need to keep the strings outside the code, stored in a file with a determined format. This format depends on the framework/library we are using, as different frameworks/libraries have specific structures they work with.

So, what will happen if we want to adapt our product to new platforms or integrate new tools and utilize different localizable file formats? Will your files be unusable? No, Localazy got your back; we'll convert the file formats for you with our Format Conversions feature.

Is localizable file conversion with Localazy free or paid?

Format Conversions are available for all users with the Localazy Professional tier and up.

See the pricing page for options

It will pay off with the first single conversion you perform—no limitations as of formats, number of operations, or conversion data volume. Once you make it a part of your workflow and automate converting localizable files, your dev life will get easier, we can guarantee that. 🤩

image.png

📋 Sample Android XML to iOS .strings conversion

To demonstrate the feature, we'll create an XML file, and we'll do an example conversion to .strings.

Simple setup

Let's start by creating a directory to keep our files organized. It will have the following layout :

.
├── locales
├── converted
├── localazy.exe
└── localazy.json

The locales folder is where we will keep the file we want to convert, and in the converted folder, we will store the converted files. All of this will have to be configured in our localazy.json file.

The localazy.exe file is the Localazy CLI; if you use a different OS, you might not have to have it downloaded and stored here.

For more information about the Localazy CLI, check The Basics – Localazy

Inside our locales folder, we'll create an Android XML file with a few strings, we'll name it en.xml:

<?xml version="1.0" encoding="utf-8"?>
<resources
    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
    <string name="android">"Android was developed by Google"</string>
    <string name="conversion">"I\'m converting files"</string>
    <string name="ios">"iOS was developed by Apple"</string>
    <string name="weather_answer">"It\'s rainy and cold"</string>
    <string name="weather_question">"How\'s the weather outside?"</string>
</resources>

Our directory will now look like this:

.
├── locales
│   └── en.xml
├── converted
├── localazy.exe
└── localazy.json

You have to configure the localazy.json file depending on what we are doing. In this case, we are doing a simple conversion between two formats, so we'll keep the configuration simple:

{
   "writeKey":"your-write-key",
   "readKey":"your-read-key",
   "upload":{
      "type":"android",
      "files":"/locales/en.xml"
   },
   "conversion":{
      "actions":{
         "type":"ios-strings",
         "output":"converted/${lang}.lproj/Localizable.strings"
      }
   }
}

As you can see, we have two sections. The upload section is built to configure the upload properties, and the conversion section is built to configure how and to what you want to convert your uploaded files into.

We also have the writeKey and readKey fields. Here you have to place your project's keys.

To get your keys, log in to your Localazy account and create a new project by choosing the format you'll use to upload. When you create the project, you'll get the keys, and then you can place them in the localazy.json configuration file.

Remember that the Format Conversions feature is only available for users with the Professional tier and up, meaning that the following steps will not function if you are on the Free plan and the feature is locked. However, you can activate a 7-day trial of the Professional plan to try everything out.

Most work is done, now you'll have to open your CMD in the root of your directory and run:

localazy upload

When this command is finished, run:

localazy download

Your directory will now look like this:

.
├── locales
│   └── en.xml
├── converted
|   └── en.lproj
|       └── Localizable.strings
├── localazy.exe
└── localazy.json

The Localizable.strings file will contain the following:

"android" = "Android was developed by Google";
"conversion" = "I'm converting files";
"iOS" = "iOS was developed by Apple";
"weather_answer" = "It's rainy and cold";
"weather_question" = "How's the weather outside?";

Easy right?

Plurals

This far, we only showed you the basics of our Android to iOS file format conversion, and our example was pretty simple with a few strings.

But, what if we throw in some plurals as well?

Let's add the following strings to our Android XML original file:

<plurals name="availableSongs">
    <item quantity="one">%d song found.</item>
    <item quantity="other">%d songs found.</item>
</plurals>

Because we're converting to iOS, our plurals will have to be placed in a .stringsdict file, meaning that we'll have to configure our localazy.json file to distinguish the plain strings from the plurals and put them in the different file format.

{
   "writeKey":"your-write-key",
   "readKey":"your-read-key",
   "upload":{
      "type":"android",
      "files":"/locales/en.xml"
   },
   "conversion":{
      "actions":[
         {
            "type":"ios-stringsdict",
            "output":"converted/${lang}.lproj/Localizable.stringsdict",
            "params":{
               "variable":"COUNT"
            }
         },
         {
            "filterPlurals":true,
            "type":"ios-strings",
            "output":"converted/${lang}.lproj/Localizable.strings"
         }
      ]
   }
}

Because we are generating a .stringsdict file, we are required to add the field variable inside params.

When we run Localazy CLI's upload and download commands, our directory will now look like this:

├── locales
│   └── en.xml
├── converted
|   └── en.lproj
|       └── Localizable.strings
|       └── Localizable.stringsdict
├── localazy.exe
└── localazy.json

Our plain strings are in the Localizable.strings file, and our plurals are in the Localizable.stringsdict file.

  • The Localizable.strings file should look like this:
"android" = "Android was developed by Google";
"conversion" = "I'm converting files";
"ios" = "iOS was developed by Apple";
"weather_answer" = "It's rainy and cold";
"weather_question" = "How's the weather outside?";
  • And Localizable.stringsdict like this:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
    <dict>
        <key>availableSongs</key>
        <dict>
            <key>NSStringLocalizedFormatKey</key>
            <string>%#@COUNT@</string>
            <key>COUNT</key>
            <dict>
                <key>NSStringFormatSpecTypeKey</key>
                <string>NSStringPluralRuleType</string>
                <key>NSStringFormatValueTypeKey</key>
                <string>d</string>
                <key>one</key>
                <string>%d song found.</string>
                <key>other</key>
                <string>%d songs found.</string>
            </dict>
        </dict>
    </dict>
</plist>

Platform Specific Key Filtering

In some cases we might need to filter some strings, for that we have the platform key filtering option.

Let's add a few strings that contain 'Android' into our Android XML file. For simplification we are not including the Plurals section here, as we only want basic strings:

<?xml version="1.0" encoding="utf-8"?>
<resources
    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
    <string name="android">"Android was developed by Google"</string>
    <string name="conversion">"I\'m converting files"</string>
    <string name="ios">"iOS was developed by Apple"</string>
    <string name="weather_answer">"It\'s rainy and cold"</string>
    <string name="weather_question">"How\'s the weather outside?"</string>
    <string name="android_love">"I love Android"</string>
    <string name="android_best">"Android is the best mobile OS"</string>
</resources>

We probably won't use the strings showing our Android affection in the iOS version of our app, so what now?

Let's add one more field in the localazy.json file:

{
   "writeKey":"your-write-key",
   "readKey":"your-read-key",
   "upload":{
      "type":"android",
      "files":"/locales/en.xml"
   },
   "conversion":{
      "actions":{
         "excludeKeys":[
            "CONTAIN:android"
         ],
         "type":"ios-strings",
         "output":"converted/${lang}.lproj/Localizable.strings"
      }
   }
}

The excludeKeys field allows you to filter out strings depending on the content of their keys.

In this case we just added the operation CONTAIN which filters out keys that contain the declared value. There are various operations available and you can add multiple operations inside an array.

Check all the available operations in the documentation

Let's run our CLI once again, and the result is:

"conversion" = "I'm converting files";
"ios" = "iOS was developed by Apple";
"weather_question" = "How's the weather outside?";
"weather_answer" = "It's rainy and cold";

📌 Closing Words

As you can see, it's effortless to convert localizable file formats with the Format Conversions feature of Localazy.

It's time to expand your project to other platforms. If file conversion is something you are battling within your CI/CD , consider getting the Localazy Professional plan and make your dev life easier with automatic file format conversions. ✌️