Skip to main content

Continuous integration in multilingual mobile application

Have you ever developed multilanguage iOS app? How did you handle translations? Did you work with the client on translations? I hope you didn’t have any problem with things mentioned about, but we had ;) We used to struggle with them in every next project. That leaded us to the idea to improve that process. We share our solution with you just below.

How it looked in the past vs how it looks now

Process looked like that:

  • We had shared google docs, for example https://drive.google.com/a/valueadd.pl/file/d/0B62idhNgYYfoT3FpNzROV1JNZ28/view?usp=drivesdk
  • Client or person responsible for the translations had to fill it in Google Docs
  • Developer needed to update the translations by hand (copying and pasting each line)
  • Xcode release was being done manually (the endless and monotonous clicking)
  • Doing manual release in Testflight. Need to click publish in the portal etc.
  • Done! After about an hour the work was finished.

As you see it wasn’t really automatic.

That’s how it looks now

  • Write fastlane testflight in console. Process is being done in the background
  • Whole process takes 1 min of Developer’s time.      

 

How it works

We have developed new flow using fastlane.tools, localise.biz and Jenkins (it’s not about our Hedgehog). It requires only one command to start deployment.

For the start we need to install fastlane `gem install fastlane` and `fastlane init` in the project directory. More about fastlane itself you can read on https://docs.fastlane.tools/

Then we synchronise translations thanks to loco and it’s api.  

                                                         

Few lines of code and our  Ruby class does the job. To initialize Loco you need api key and path to directory where *.lproj directories are. Example:

LOCO_API_KEY = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
LOCO_DESTINATION_DIR = "#{__dir__}/../acme_ios/"

LOCO = IOSLoco.new(LOCO_API_KEY, LOCO_DESTINATION_DIR)

 

Let’s imagine that our application has English and Danish translations, so sync_languages method takes array with two languages. 

Loco api key can be found on the right of the project preview in developer tools tab.

before_all do
  Encoding.default_internal = Encoding::UTF_8
  Encoding.default_external = Encoding::UTF_8

  LOCO_API_KEY = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
  LOCO_DESTINATION_DIR = "#{__dir__}/../acme_ios/"

  LOCO = IOSLoco.new(LOCO_API_KEY, LOCO_DESTINATION_DIR)
end

desc "Sync translations"
lane :translations do
  LOCO.sync_languages(["en","da"])
end

 

the result of `fastlane translations` command will be:

gif

If we want to synchronise translations just before publishing to the testlight/appstore we can move the code just before `gym` execution in our lane.

desc "Submit a new develop build to  Testflight"
lane :develop do
  cert
  sigh
  increment_build_number
  LOCO.syncLanguages(["da"])
  LOCO.syncMainLanguage("en")
  gym(scheme: "Develop")
  pilot
end

 

Whole Fastfile should looks like:

fastlane_require 'json'
require __dir__+'/libs/IOSLoco.rb'

fastlane_version "2.55.0"

default_platform :ios


platform :ios do

  before_all do
    Encoding.default_internal = Encoding::UTF_8
    Encoding.default_external = Encoding::UTF_8

    LOCO_API_KEY = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
    LOCO_DESTINATION_DIR = "#{__dir__}/../acme_ios/"


    LOCO = IOSLoco.new(LOCO_API_KEY, LOCO_DESTINATION_DIR)
  end

  desc "Sync translations"
  lane :translations do
    LOCO.sync_languages(["da","en"])
  end

  desc "Submit a new develop build to  Testflight"
  lane :develop do
    cert
    sigh
    increment_build_number
    LOCO.sync_languages(["da","en"])
    LOCO.sync_main_language("en")
    gym(scheme: "Develop")
    pilot
  end
  [...]
end

 

I hope you found that article helpful. If you have better ideas for solving that challenge let me me know at blog@valueadd.pl. If you have any questions do the same and I will help you out.

 

Where should we send price of that project?