Add multi language support in the runtime of iOS app

Most of the app in the appstore will not allow you to change the app language, they took the language from your sytem language on your iOS device. But there are also numerous of app that allow you to change the language and require you to re-open the app in order the language to be set.

This tutorial will enable you to make your app speak many languages without require user to re-close or restart the device.

Enable multi language support

Enabling localization is quite easy, there are only few clicks on Xcode.

- Add new String file. Click File->New->File on your project. Make sure you have selected a directory on your Project Navigator.

- Search for Resource section, and choose Strings File. Choose whatever name you like, but in this tutorial let say LanguageFile.string

- Once created, Go to Inspector on your right side, and click on the button Localize.

Localize button

When you finished adding the main language file, now we are able to add supported language.

- On your Project Navigator, click on the project name. Usually project navigation is on your left side (the sidebar).

- Once the right side of Xcode changed, click on the Project name, above the Target

- Click on the Info tab, then go to Localizations section.

- Click on the plus, and choose the language you want to support

Check only LanguageFule.strings

- Check only the LanguageFile.strings on the image above. This will enable the string file we have created an ability to have multiple files based on the language you have chosen.

- Once finished, you will be able to see the LanguageFile.strings will have more than  1 files.

Language File

Add the class

Add the class below to your project. Please change the variable langSupport based on the supported language you have chosen above.

import UIKit

class DTLanguage: NSObject {
    private let langSupport = ["en", "ar"]
    private static let shared = DTLanguage()
    
    class func initLanguage() {
        let currentLanguage = (Locale.current as NSLocale).object(forKey: NSLocale.Key.languageCode)! as! String
        
        if let selectedLanguage = UserDefaults.standard.object(forKey: "language") as? String {
            self.set(selectedLanguage)
        }
        else if DTLanguage.shared.langSupport.contains(currentLanguage) {
            self.set(currentLanguage)
        }
        else if let firstLang = DTLanguage.shared.langSupport.first {
            self.set(firstLang)
        }
        else {
            self.set("en")
        }
    }
    
    class func set(_ lang: String) {
        UserDefaults.standard.set(lang, forKey: "language")
    }
    
    class func get(_ key: String) -> String {
        if let lang = UserDefaults.standard.object(forKey: "language") as? String {
            
            let path = Bundle.main.path(forResource: lang, ofType: "lproj")
            
            let bundle = Bundle(path: path!)
            return (bundle?.localizedString(forKey: key, value: key, table: "LanguageFile"))!
        }
        else {
            return key
        }
    }
    
    class func current() -> String {
        if let lang = UserDefaults.standard.object(forKey: "language") as? String {
            return lang
        }
        else {
            if let lang = Locale.current.languageCode {
                DTLanguage.set(lang)
                return lang
            }
            else {
                DTLanguage.set("en")
                return "en"
            }
        }
    }
}

Using the class

Open your AppDelegate.swift file. Added this line on the didFinishLaunchingWithOptions method. This line will detect the current system language for the very first time the user open the app, and use that language to set. If the system language is not available within the supported language, it will set the first supported language on your array at the class.

DTLanguage.initLanguage()

Added few lines on the LanguageFile string with the same format as below:

'sign_in' = "Sign In";
'email' = "Email Address";

And call each line by typing this line:

let signInText = DTLanguage.get("sign_in")
let emailText = DTLanguage.get("email")

If you want to know which language is currently active:

let current = DTLanguage.current()

If you want to change the current language:

DTLanguage.set("en") // if you want to change to english
DTLanguage.set("ar") // change to arabic

Hope it helps.

Show Comments