How to Create Localizable and Use for Swift

Gorkem Gur
Mobiroller Tech
Published in
5 min readApr 4, 2022

We are using localizable files to support other languages for example, we created an English-based application but our users need to see their language on our app. What should we do ?

We need to import these files to our project and translate our string variables to their languages.

//  String+LocalizedBundleTableName.swift
// Localize_Swift
//
// Created by Vitalii Budnik on 10/7/16.
// Copyright © 2016 Roy Marmelstein. All rights reserved.
//

import Foundation

public extension String {

func localized(using tableName: String?, in bundle: Bundle?) -> String {
let bundle: Bundle = bundle ?? .main
if let path = bundle.path(forResource: LocalizeExample.currentLanguage(), ofType: "lproj"),
let bundle = Bundle(path: path) {
return bundle.localizedString(forKey: self, value: nil, table: tableName)
}
else if let path = bundle.path(forResource: LCLBaseBundle, ofType: "lproj"),
let bundle = Bundle(path: path) {
return bundle.localizedString(forKey: self, value: nil, table: tableName)
}
return self
}

func localizedFormat(arguments: CVarArg..., using tableName: String?, in bundle: Bundle?) -> String {
return String(format: localized(using: tableName, in: bundle), arguments: arguments)
}

func localizedPlural(argument: CVarArg, using tableName: String?, in bundle: Bundle?) -> String {
return NSString.localizedStringWithFormat(localized(using: tableName, in: bundle) as NSString, argument) as String
}

}
//
//
// Localize.swift
// Localize
//
// Created by Roy Marmelstein on 05/08/2015.
// Copyright © 2015 Roy Marmelstein. All rights reserved.
//
import UIKit/// Internal current language key
let LCLCurrentLanguageKey = "LCLCurrentLanguageKey"
/// Internal current language key
let LCLAppleLanguagesKey = "AppleLanguages"
/// Default language. English. If English is unavailable defaults to base localization.
let LCLDefaultLanguage = "en"
/// Base bundle as fallback.
let LCLBaseBundle = "Base"
/// Name for language change notification
public let LCLLanguageChangeNotification = "LCLLanguageChangeNotification"
/**
Swift 1.x friendly localization syntax, replaces NSLocalizedString
- Parameter string: Key to be localized.
- Returns: The localized string.
*/
public func Localized(_ string: String) -> String {
return string.localized
}
/**
Swift 1.x friendly localization syntax with format arguments, replaces String(format:NSLocalizedString)
- Parameter string: Key to be localized.
- Returns: The formatted localized string with arguments.
*/
public func Localized(_ string: String, arguments: CVarArg...) -> String {
return String(format: string.localized, arguments: arguments)
}
/**
Swift 1.x friendly plural localization syntax with a format argument

- parameter string: String to be formatted
- parameter argument: Argument to determine pluralisation

- returns: Pluralized localized string.
*/
public func LocalizedPlural(_ string: String, argument: CVarArg) -> String {
return string.localizedPlural(argument)
}
public extension String {
/**
Swift 2 friendly localization syntax, replaces NSLocalizedString
- Returns: The localized string.
*/
/**
You need to change Example.Example with your project Bundle Identifier
*/
var localized: String {
return localized(using: nil, in: Bundle(identifier: "Example.Example"))
}
/**
Swift 2 friendly localization syntax with format arguments, replaces String(format:NSLocalizedString)
- Returns: The formatted localized string with arguments.
*/
func localizedFormat(_ arguments: CVarArg...) -> String {
return String(format: localized, arguments: arguments)
}

/**
Swift 2 friendly plural localization syntax with a format argument

- parameter argument: Argument to determine pluralisation

- returns: Pluralized localized string.
*/
func localizedPlural(_ argument: CVarArg) -> String {
return NSString.localizedStringWithFormat(localized as NSString, argument) as String
}
}
// MARK: Language Setting Functionsopen class LocalizeExample: NSObject {

/**
List available languages
- Returns: Array of available languages.
*/
open class func availableLanguages(_ excludeBase: Bool = true) -> [String] {
var availableLanguages = Bundle.main.localizations
// If excludeBase = true, don't include "Base" in available languages
if let indexOfBase = availableLanguages.firstIndex(of: "Base") , excludeBase == true {
availableLanguages.remove(at: indexOfBase)
}
return availableLanguages
}

/**
Current language
- Returns: The current language. String.
*/
open class func currentLanguage() -> String {
if let currentLanguage = UserDefaults.standard.object(forKey: LCLCurrentLanguageKey) as? String {
return currentLanguage
}
return defaultLanguage()
}

/**
Current character direction
- Returns: The current character direction. Locale.LanguageDirection.
*/
open class func currentCharacterDirection() -> Locale.LanguageDirection {
return Locale.characterDirection(forLanguage: currentLanguage())
}

open class func semanticAttribute() -> UISemanticContentAttribute {
return self.currentCharacterDirection() == .rightToLeft ? .forceRightToLeft : .forceLeftToRight
}
/**
Default language
- Returns: The app's default language. String.
*/
open class func defaultLanguage() -> String {
var defaultLanguage: String = String()
guard let preferredLanguage = Bundle.main.preferredLocalizations.first else {
return LCLDefaultLanguage
}
let availableLanguages: [String] = self.availableLanguages()
if (availableLanguages.contains(preferredLanguage)) {
defaultLanguage = preferredLanguage
}
else {
defaultLanguage = LCLDefaultLanguage
}
return defaultLanguage
}

/**
Get the current language's display name for a language.
- Parameter language: Desired language.
- Returns: The localized string.
*/
open class func displayNameForLanguage(_ language: String) -> String {
let locale : NSLocale = NSLocale(localeIdentifier: currentLanguage())
if let displayName = locale.displayName(forKey: NSLocale.Key.identifier, value: language) {
return displayName
}
return String()
}
}

And the extension file should be look like that :

Let’s begin , First we need to create a group called support or anything but you need to remember localizable files will under this group.

As in the picture below we need to create a string file called Localizable

Then you should to select ExampleApp’s Launchsreen.storyboard after that you should click Show the file inspector on the right side that one like a page curled at the top right. After clicked that page button you can see Localize… button right of the screen you can select language from here. If you can’t see your language in here don’t worry we will add it later , just choose English or whatever you want language from spinner and click Localize.

Well , if you couldn’t get error until this step we can create other localizable languages.

Choose ExampleApp top of the folders and then select your ExampleApp under the Project title you can see the Localizations fields. Click the “+” button and choose your localizable language.

The hierarchy of the project should be like this :

If you have completed all the steps to get here select Localizable.strings file under the support file so should be an empty localizable file.

Sample Localization.strings file code ;

Localizable (English) ->//MARK: - GENERAL USAGE"example-message" = "Example Label";Localiable (Turkish) ->//MARK: - GENERAL USAGE"example-message" = "Örnek Yazı";

For ViewController we can use the following example structure

Class MainViewController {private struct Constants {static variableName: String { return "example-message".localized }}func setup() {exampleLabel.text = Constants.variableName}}

You can see we need to put “:” like C Programming Language :) at the end of line and we can use our variables.

If You want to use localizable file with storyboard you need to create extension like that

import Foundation
import UIKit
public extension UILabel {@IBInspectable public var localizedText: String? {
get {
return text
}
set {
text = NSLocalizedString(newValue ?? "", comment: "")
}
}
}

The example code above allow us to access our localizable variables from xib(design) file while using storyboard.

Finally! We got the result on simulator

Final Result Of Localization

--

--