Advantages And Disadvantages of Dynamic And Static Localization

Advantages And Disadvantages of Dynamic And Static Localization

Table of contents

In this article, we would like to share our experience and expertise regarding dynamic and static localization. We want to discuss in detail the benefits and possible disadvantages of each technique - perhaps, this information will simplify your development process in the future!

So, here goes!

Dynamic localization

Let's say you have just released your application in the App Store, and now you need to change the text on the button: for example, instead of the word "Next", you'd like to see "Continue". You have two ways: either to update your app version or to integrate dynamic localization for the project before releasing the version of the application for App Store. We offer a more detailed discussion of the second option.

So, let's see what should be considered in order to implement dynamic localization…

  • API implementation on the server side. First of all, you should provide a possibility to add rows, namely a key and a value. In addition, there should be a flag able to help to determine if a certain row has been created or changed (for example, the date of creation or modification). And, of course, an API call must also be implemented; using it, you can request the entire list of rows you need;
  • the file with the extension .plist which is located in the application project. It stores all localization rows. Further, in the article, we’ll show show it in detail
  • database;
  • several methods aimed to implement the localization process directly in the application itself.

File with the .plist extension

If you open the source code of the file, you will see the following structure:

<?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>ru_date_localize</key>
        <string>2017-10-09T13:52+02:00</string>
        <key>localized_array</key>
        <array>
            <dict>
                <key>key</key>
                <string>ru_route</string>
                <key>value</key>
                <string>Мой профиль</string>
            </dict>
            <dict>
                <key>key</key>
                <string>ru_for_now</string>
                <key>value</key>
                <string>На Сейчас</string>
            </dict>
            <dict>
                <key>key</key>
                <string>ru_driver_info_is_loading</string>
                <key>value</key>
                <string>Загрузка информации о водителе...</string>
            </dict>
            <dict>
                <key>key</key>
                <string>ru_car</string>
                <key>value</key>
                <string>Автомобиль</string>
            </dict>
            <dict>
                <key>key</key>
                <string>ru_order_created</string>
                <key>value</key>
                <string>Заказ создан!</string>
            </dict>

            <dict>

Here is an example for Russian localization. After the first three standard rows, we see a dictionary. The first key/value is the date the file was last modified. Then comes an array consisting of n-th number of dictionaries (and the number of rows corresponds to it). However, in each dictionary, there are two values: the first of them contains the key of the row, and the second one includes the row itself. This structure is necessary for further work with the database.

This file is needed to reduce the download time of the application. Instead of getting the rows from the server every time you start the app, it's enough to read them from the file just once and save them to the database. Thus, we should query the server for only those rows that have been changed after the date of creation or editing of this file.

Filling this file manually can be a too tedious process, so it's better to implement the possibility of downloading it from the server.

Database

We have used Realm to save all the data from the plist and the updates that come from the server. As you can see, the structure of the class is fairly simple and contains a key and a value.

MyLocalizationString.h

#import <Realm/Realm.h>

@interface MyLocalizationString : RLMObject

@property (strong, nonatomic) NSString *key;

@property (strong, nonatomic) NSString *value;

@end




MyLocalizationString.m

@implementation MyLocalizationString

+ (NSString *)primaryKey {    

return @"key";

}

@end

What methods should you implement for localization?

Let's briefly enumerate what needs to be done to make the described system a working one:

  • comparison of the date of the .plist file and the latest localization changes
  • saving rows to the database and specifying the date of localization of the .plist file
  • checking rows on the server
  • creating a class for working with localized rows

So, first, you should find out whether you need to save your rows to the database. To achieve this, you can compare the saved dates in the database and in the plist file. As you have noticed, besides the rows, the plist file contains the date of its modification. As for the date linked to the database, it can be saved to NSUserDefaults. It is important to compare these dates and decide on your future actions. For example, if a plist file has a later date, we update the information in NSUserDefaults so that these values match.

Next, we need to check if new or changed rows have appeared on the server. If they did, then, in addition to updating the database, you must also update the date.

And, finally, the last point is to implement a class for working with localized rows.

Pros and cons of dynamic localization

Let's discuss what advantages and disadvantages the proposed system has.

So…

Pros of dynamic localization:

  • the possibility to edit rows without updating the application in the App store.
  • the decrease in the download speed (if you have a .plist file and save the rows to the database)

Cons of dynamic localization:

  • there is a possibility of slowing down the loading speed of cells when scrolling. Suppose you have a table with cells each of which has more than one localized row, and in addition, it is loaded with UI elements. With fast scrolling, this can cause a braking effect, since the rows are called from the database;
  • rows are being duplicated. It means that in addition to the file with plist rows, you will have a copy in the database.

Of course, when implementing dynamic localization, it is necessary to carefully work out the algorithm for saving and updating the rows to the database. Otherwise, the rows may be updated incorrectly, and you will have to solve this problem.

Static localization

We think you understand that we are talking about local files that are stored directly in the project itself. But we would like to tell you not about the NSLocalizedString class, but about several factors that simplify and speed up our work, namely:

  • Auto File Localize Script - script to automatically create a file with localization for each screen;
  • SwiftGen - a library which allows you to get localized rows in a more convenient and visual form.

Auto File Localize Script

Let's say you create a new project and add support for multiple languages. With each addition of the UI element, you will need to go into the Identity Inspector and copy its identifier. Moreover, you will have to repeat this "ritual" with all the new elements.

Therefore, our Agilie team has written a script that automatically creates a key-value for each UI-element containing text, and saves it to a file intended for localization. It is being executed while we're building a project. That is, it runs through all storyboards and xib files, parses rows for all elements and saves them (or updates their values) to the appropriate files aimed for localization. If your project supports multiple languages, the script will save and update keys and values to files for several languages.

The integration process is quite simple.

#1 Step

First, we add file to the project.

#2 Step

Now we click on the "+" icon in the Project Targets Block (a Build Phase tab), select New Run Script Phase and prescribe the path to our script. To start with the project name, add $ SRCROOT at the beginning.

 

#3 Step

Add Strings File with the same name as the storyboard or xib file has.

#4 Step

After that, you can add rows to the UI elements or build the project if you already have the rows that you want to add to the Strings File. In the end, you have such a file (take a look at the picture).

Pros and cons of Auto File Localize Script

Now it's time to talk about the advantages and disadvantages of Auto File Localize Script

Pros:

  • simple script integration
  • the development process is accelerating. No need to waste time creating a key and a value for each UI element.

Cons:

  • there is no backward compatibility. For example, if you change a row in a Strings file, it will not change for the UI element.
  • build time is slowed down. If you increase the number of rows and Strings files, the time for building or running the application on the simulator or device will increase, because the script needs time to go through all the files and find the changes made.
  • when changing a row in a UI element, similar changes occur in all language files.

SwiftGen

SwiftGen is a tool for automatically creating code in the Swift language for the resources of your projects; the goal is to make them more convenient. Clicking on the link, you will see a guide for integrating this system into the project.

After integrating Localizable.strings, you will have the following file generated, which will call all the rows from Localizable.strings and create a case for each row in the enum. With every change in Localizable.strings, it will automatically call the new case during the build process.

 

 

 

 

 

 

 

 

 

 

 

 

We suggest that you take a look at the difference in working with the standard NSLocalizedString and the SwiftGen tool. Dealing with SwiftGen, the variable named alertMessage is one of the cases in the enom. Also, we would like to add that this tool has the ability to work with fonts, colors, pictures, storyboards and xib-files.

BEFORE

let alertDescription = NSLocalizedString("alert_message", comment: "")

AFTER

let alertDescription = L10n.alertMessage

Hopefully, our article was useful to you. If you have any questions - feel free to ask! We will be happy to discuss them with you.

 

 

Rate this article
15 ratings, average 4.80 of out 5
Table of contents
Get in touch
Next posts
Animated Toggle Menu
Animated Toggle Menu
Helen Vakhnenko
Helen Vakhnenko
From Concept to Reality: NFT Game Development Explained
From Concept to Reality: NFT Game Development Explained
Sergii Gladun
Sergii Gladun
Secure Smart Contract Design: Best Practices in Solidity Programming
Secure Smart Contract Design: Best Practices in Solidity Programming
Sergey Melashich
Sergey Melashich