Improving Localizable Strings Using SwiftGen
The foundation for displaying text onscreen for iOS applications
Localizable strings are the foundation for displaying text onscreen for iOS applications. These are typically stored in .strings
files that are switched out depending on the user’s locale.
Let’s take a look at how you would typically go about it. You would have a .strings
file for each language you are supporting. Each file may look something like the following:
"action.cancel"="Cancel";
"action.logout"="Log out";
"action.ok"="Ok";"welcome.title"="Welcome!";
Typically, you would then access it via a localized string using the key to look it up.
let localizedTitle = NSLocalizedString("welcome.title", comment: "")
However, this is quite a lengthy thing to type every time you want a localized string. We also don’t need to use the comment parameter, so we could add a string extension to make it read more cleanly, like the following:
// MARK: String extensionextension String {
var localized: String {
return NSLocalizedString(self, comment: “”)
}
}// Usage:let localizedTitle = "welcome.title".localized
This is a much cleaner solution, although there are still a few problems with it. Let’s look at them in more depth.
Firstly, you can write any key you like as it’s just a string and there is no guarantee that it will be present in the localized .strings
file whatsoever. If it isn’t present, it would result in the key being displayed as the value instead, leaving a broken experience for the end user.
Secondly, it requires constantly switching views between the localized .strings
file to find the key you’re after to copy and paste it into the desired view or view controller.
Surely there has to be a better way.
Introducing Statically Compiled Localized Strings
This next step is going to require a dependency called SwiftGen. It can be added to your project via Cocoapods, Carthage, or Swift package manager.
SwiftGen is a Swift code-generator tool that can generate code during Xcode’s build phase. We want to add the following code as a new run script phase on the application’s main target, or the target that contains the localizable .strings
files.
TargetName=YourAppsMainTargetName
SourcePath=$SOURCE_ROOT/$TargetName/PathToLocalizableStringsFile.strings
Output=$SOURCE_ROOT/$TargetName/PathToOutputFileIncludingName.swift$PODS_ROOT/SwiftGen/bin/swiftgen strings -p $PODS_ROOT/SwiftGen/templates/strings/structured-swift4.stencil $SourcePath — output $Output — param enumName=Localizable
Be sure you replace the following variables:
YourAppsMainTargetName
PathToLocalizableStringsFile.strings
PathToOutputFile.swift
After a build, it will generate the file containing enums with static constants representing all of your localized strings. Remember to add the generated file to Xcode’s .project
file.
Now you can access your localized strings using Xcode’s autocomplete.
And take advantage of option-clicking on the variable’s name to access Xcode’s quick help to see the localized .strings
value.
Hopefully, this has taught you something new and can help you improve upon how you use localized strings for your iOS and Mac OS development.