Swift helper classes for Apple iOS strings

The Respresso generates Swift helper classes, so you can reference localizations from Swift source code in a typo-safe way with auto-completion support in Xcode. For this, Respresso generates 2 helper structs:

  • RespressoStringKeys: Contains all localizations keys as readonly properties.
  • RespressoStrings: Contains a readonly property for each localization key that returns locale specific translation. In case the key has localization variables, a function will be generated with them as arguments.

This format can't be imported to Respresso, it's output only.

How Respresso generates it?

This format is (mostly) language independent, thus you will get the same files regardless of the added languages.

You can expect to get the following file in the swift sync group:

  • RespressoStrings.swift

Let's assume you have a single localization with two registered variables in Respresso:
mainScreen.accountBalance:

  • English (en): Balance: {{ currency }} {{ balance }}
  • English (en-GB): Unspecified
  • Hungarian (hu): Egyenleg: {{ balance }} {{ currency }}

Where variable formats in Respresso is the following: currency is %s (or equivalent %@), and balance is %.2f.

It will output 1 file, including the following enum and structs:

import UIKit
enum RespressoLanguage: String, CaseIterable {
    case en = "en"
    case enGB = "en-GB"
    case hu = "hu"
    static let defaultLanguage = RespressoLanguage.en
}
struct RespressoStringKeys {
    public static let mainScreenAccountBalance : String = "mainScreen.accountBalance"
}
struct RespressoStrings {
    /// There will be some internal variables and functions not shown here
    
    /// Force a specific language to be used when accessed localizations through RespressoStrings
    static var language: RespressoLanguage? { /* implementation */ }
    
    /// Dynamically access localizations
    /// Calls NSLocalizedString(...) with RespressoStrings.language specific bundle
    public static func localizedString(key: String, comment: String)  -> String { /* implementation */ }
    
    /** mainScreen.accountBalance */
    public static var mainScreenAccountBalance : String {
        return localizedString(key: RespressoStringKeys.mainScreenAccountBalance, comment: "mainScreen.accountBalance")
    }
    /** mainScreen.accountBalance VARIABLES: currency | %.2f; balance | %s */
    public static func mainScreenAccountBalance(currency: Double, balance: String) -> String {
        return String(format: mainScreenAccountBalance, currency, balance)
    }
}

How to use RespressoStrings.swift

RespressoStrings brings typo safe support to access localizations form code, even with parameters. You can easily force a specific language instead of the system default.

Access localized text

Each time you want to use a localized text from Respresso, you should access it through the RespressoStrings struct. This is no magic, it uses the standard NSLocalizedString(...) and String(format: ...) but you will get auto-completion support in Xcode to boost your productivity. This will guarantee that the key is always matching the key in the .strings file, there is no more place for typos or missing localizations. For localizations with variables, you will also get a function with the proper parameter list with the proper types based on variable formatting set in Respresso.

How to access localizations:

var localized = RespressoStrings.mainScreenAccountBalance 
//  localized = "Balance: %1$@ %2$.2f" on English devices

var formattedWithParams = RespressoStrings.mainScreenAccountBalance("USD", 143.1267) 
//  formattedWithParams = "Balance: USD 143.13" on English devices

var dynamicKey = RespressoStrings.localizedString(key: "mainScreen.accountBalance", comment: "...")
//  dynamicKey = "Balance: %1$@ %2$.2f" on English devices - same as localized

Force a specific language

Many apps provide language settings within the app that is a tedious task to implement in iOS as language switching is not available. Thus, we decided to bring you that feature out of the box if you use RespressoStrings to access localizations. For this, you get the RespressoLanguages enum and the RespressoStrings.language property.

Switch language:

RespressoStrings.language = RespressoLanguage.hu // Force Hungarian language
var localized = RespressoStrings.mainScreenAccountBalance // "Egyenleg: %2$.2f %1$@"
RespressoStrings.language = nil // Return to system default language (English)
localized = RespressoStrings.mainScreenAccountBalance // "Balance: %1$@ %2$.2f"

Available languages:
To build a dynamic language selector, you will need to iterate over all the languages, therefore the RespressoLanguage enum is a CaseIterable. In addition to this, it provides the defaultLanguage property that will contain the language enum value that corresponds to the language marked as default in Respresso. Let's see an example:

var languages = RespressoLanguage.allCases.map({ "\($0)" }).joined(separator: ", ")
//  languages = "en, en-GB, hu"
var defaultLanguage = RespressoLanguage.defaultLanguage
//  defaultLanguage = RespressoLanguage.en

Access localization keys

If you want to access the localization key that is present in the RespressoStrings.strings files, you have to use the RespressoStringKeys struct:

var key = RespressoStringKeys.mainScreenAccountBalance // returns "mainScreen.accountBalance"

This can be used to access localizations using the standard NSLocalizedString(key, ...) or to look up localizations from a dynamically downloaded json from your backend.