How to convert Android XML to iOS .strings using Localazy
Tags: ios, android, i18n, tutorial
Published: 2021-07-20 07:36:38

**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](https://localazy.com) comes with the  [Format Conversions](https://localazy.com/docs/general/format-conversions-add-on) feature and vast support of  [formats and integrations](https://localazy.com/integrations) you can utilize by downloading our multiplatform  [command-line interface (CLI) tool](https://localazy.com/docs/cli/the-basics).

## 🔖 Why Android XML to iOS .strings?
[Android ](https://localazy.com/dictionary/android) and [iOS ](https://localazy.com/dictionary/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 ](https://localazy.com/android) and [iOS](https://localazy.com/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](https://localazy.com/dictionary/externalized-string), 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](https://localazy.com/blog/guide-preparing-application-for-i18n-l10n-localazy) 

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](https://localazy.com/docs/general/format-conversions-add-on) feature.

### Is localizable file conversion with Localazy free or paid?

Format Conversions are available for all users with the Localazy [Professional](https://localazy.com/docs/general/localazy-professional-tier) tier and up.

> See the [pricing page](https://localazy.com/pricing) 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](https://cdn.hashnode.com/res/hashnode/image/upload/v1626699202828/YxYpcvOaT.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](https://localazy.com/docs/cli/the-basics) 

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](https://localazy.com/docs/general/format-conversions-add-on) is only available for users with the [Professional tier](https://localazy.com/docs/general/localazy-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](https://localazy.com/docs/cli/excluding-string-keys) 

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](https://localazy.com/dictionary/continuous-integration) , consider getting the [Localazy Professional plan](https://localazy.com/pricing) and make your dev life easier with automatic file format conversions. ✌️