App Localization Tips With Swift

Introduction

Getting Started

"<key>" = "<value>";
"loading_data" = "Loading Data...";
"data_loaded" = "Data Loaded!";

String Extension

func NSLocalizedString(_ key: String, tableName: String? = default, bundle: Bundle = default, value: String = default, comment: String) -> String
let string = NSLocalizedString("data_loaded", comment: "") // Data Loaded!
extension String {    func localized(bundle: Bundle = .main, tableName: String = "Localizable") -> String {
return NSLocalizedString(self, tableName: tableName, value: "**\(self)**", comment: "")
}
}
"data_loaded".localized() // Data Loaded!
"hello_world".localized() // **hello_world**

Table Names Handling

"loading_data" = "Loading Data...";
"data_loaded" = "Data Loaded!";
"data_loaded".localized(tableName: "DataLoader") // Data Loaded!
enum DataLoaderStrings: String {
case loadingData = "loading_data"
case dataLoaded = "data_loaded"
}
enum DataLoaderStrings: String {
case loadingData = "loading_data"
case dataLoaded = "data_loaded"
var localized: String {
return self.rawValue.localized(tableName: "DataLoader")
}
}
let string = DataLoaderStrings.loadingData.localized // Loading Data...
protocol Localizable {
var tableName: String { get }
var localized: String { get }
}
// 1
extension Localizable where Self: RawRepresentable, Self.RawValue == String {
var localized: String {
return rawValue.localized(tableName: tableName)
}
}
enum DataLoaderStrings: String, Localizable {
case loadingData = "loading_data"
case dataLoaded = "data_loaded"

var tableName: String {
return "DataLoader"
}
}

UIKit Components

final class UILocalizedLabel: UILabel {    override func awakeFromNib() {
super.awakeFromNib()
text = text?.localized()
}
}
final class UILocalizedButton: UIButton {    override func awakeFromNib() {
super.awakeFromNib()
let title = self.title(for: .normal)?.localized()
setTitle(title, for: .normal)
}
}
final class UILocalizedTextField: UITextField {    override func awakeFromNib() {
super.awakeFromNib()
text = text?.localized()
}
}
@IBDesignable final class UILocalizedLabel: UILabel {
//...
}
@IBInspectable var tableName: String?
@IBInspectable var tableName: String? {
didSet {
guard let tableName = tableName else { return }
text = text?.localized(tableName: tableName)
}
}
@IBDesignable final class UILocalizedLabel: UILabel {    @IBInspectable var tableName: String? {
didSet {
guard let tableName = tableName else { return }
text = text?.localized(tableName: tableName)
}
}
}

Pluralization

if numFiles == 1 {
return "There is one file"
} else if numFiles > 1 {
return "There are \(numFiles) files"
}
let countFiles = 1
let formatString = "pending_files_%d_%d".localized()
let result = String(format: formatString, countFiles, countFiles) // There is one file

Conclusion

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store