Code Completion for Your App's Localisations with DJAStrings

3 July 2023

In the previous article we looked at the advancements that Apple has made in string localisation with the newly introduced String Catalogs for Xcode 15. Today we will look at how a new development tool, DJAStrings, makes using your app's localisations a breeze, with advanced code-completion and documentation features coming for free out of the box.

Why Code Complete Localisations?

Localised strings are accessed on Apple platforms using a String based API - the localisation's key is passed to the NSLocalizedString function in order to access the value for the user's language:

myLabel.text = NSLocalizedString("welcome.title", comment: "")

Whilst this works, this API leaves a lot to be desired. If there is a typo in the key, the code will still compile. If the localisation is removed from the app's localisation resources, the code will still compile. The story is the same with localisations that contain placeholders:

myLabel.text = String.localizedStringWithFormat(NSLocalizedString("welcome.new_messages", comment: ""), 14, 3)

This has the same problems as before, but even worse, we are passing placeholder parameters with no context as to what the values relate too. If we pass too few or too many parameters, or pass values of the wrong type, then - you guessed it - the code will still compile.

Ultimately, this String based API does not allow the compiler to help us when working with localised strings. We cannot see what text will actually be shown to the user, do not know if we are passing the correct values for placeholders, and will even have our app break without warning if the localisations change.

Wouldn't it be better if we could access our localisations as first-class Swift symbols and functions, automatically kept in sync with our localisation resources?

Introducing DJAStrings

DJAStrings is a command-line tool, built using Swift, that integrates with Xcode's build process, ingesting your project's String Catalogs to produce a Swift source file to simplify access to your app's localisations. As an example, let's see how those localisations we used earlier would be accessed after integrating DJAStrings:

myLabel.text = DJAStrings.Welcome.title

We are now setting our label's text value using a first-class Swift symbol. If the localisation's key is changed, or the localisation is removed altogether, then our code will no longer compile. This ensures that we always use the string that we mean to use. Speaking of the string itself, let's see how the integrated documentation looks for this localisation:

Inline documentation for a simple localisation.
Inline documentation for a simple localisation.

The documentation shows the string value of the localisation, making it a simple option+click to check that we're using the correct value for our label. Now let's look at the example that used a localisation containing placeholders:

myLabel.text = DJAStrings.Welcome.newMessages(messageCount: 14, inboxCount: 3)

Here, we gain the benefits described for the previous example, but also benefit from named parameters, and can no longer pass an incorrect number of arguments or pass the wrong data type. The automatically generated documentation is also taken a step further:

Inline documentation for a localisation containing multiple pluralised substitutions.
Inline documentation for a localisation containing multiple pluralised substitutions.

DJAStrings has generated examples of how our localisation provides a string for all of the possible combinations of the localisation's placeholders. We also receive similar examples for localisations that vary by device type:

Documentation for a localisation containing device variations.
Documentation for a localisation containing device variations.

For this localisation, the documentation show each string value per specified device type.

DJAStrings has resolved all of the issues we described earlier that plague the NSLocalizableString string-based API. If a localisation is modified or removed, the compiler can let us know immediately so that we can take the actions necessary to get our app working again. We can find out what text will be shown to our users quickly, with a simple look at the documentation that integrates seamlessly in to Xcode's editor and Quick Help inspector panels. The experience of working with localisations that accept placeholders is also greatly improved, thanks to named parameters and data type checking. To try out DJAStrings in your Xcode 15+ compatible projects with String Catalogs, head over to the DJAStrings GitHub repository and follow the instructions in the installation guide to get started.