comments 6

#27 Localize your strings swiftly

Hey, long time no see! It’s because we’re working on two important issues, stay tuned! This issue will be short and it will show you how you can define and access localized version of your strings in a swift manner!

NSLocalizedString

In Xcode we can easily create a Localizable.strings file in which one can define pairs of key and value strings that can be used throughout our application. A sample file would look like this:

If we wanted to create e.g. an Italian version of our app, we would have to create another Localizable.strings and put Italian version of strings (values). Just use ⌘⇧N (CMD + SHIFT + N) shortcut to create new file, type strings in filter field and select Strings File. Name the file Localizable.strings:


You can edit the file with localisations:


Once you decide on creating a translation, select project file in Project navigator and in Editor area. Go to Localizations section, tap + button and select a language:


Then select files you want to localize (only Localizable.strings in our case):


And start translating your strings :)!

You can check full tutorial from Ray Wenderlich linked in Resources section at the bottom of the post. The tutorial is for an ancient 😉 language called Objective-C, but yet it’s still one of my favourite languages (after Swift of course!).

Ok, we have those files, but what’s next? To use such strings we have to call NSLocalizedString(key:comment:) function:

Looks kinda ancient 😂. Do we really need this longNSLocalizedString(key:comment:) calls? And what’s the comment param, left here empty?

You can pass a hint for a translator inside this argument, e.g. NSLocalizedString(key:"Hello", comment: "This is the string shown on the first screen after app launch, to welcome the user"). The comment is used by Xcode when exporting files for localization, but more on that can be found in Apple’s Internationalization and Localization Guide.

But still, do I really need to use such approach in my Swift code 🐦 !?

Swiftier way

No, a swifter way exists. Thanks to extensions, we can extend types and classes with functions and static variables. Hence, we can extend String. But before that, let’s create a simpler version of NSLocalizedString(key:comment:) without comment param, in order not to type the empty comment hundreds of times throughout the file, if we don’t intend to use comment hints for our translations 👹.

We can mark this function as fileprivate so nobody would use this function unintentionally outside the file with our strings, but I can stay internal or public as well, doesn’t matter. Oh, btw. you can create a Strings+Localized.swift file in which your Swift strings can be kept. So what’s now?

Now we will extend the String type to include our localized versions of strings:

You can use such an approach even without Localizable.strings file at all, just to have in mind that your app might need translation in the future. Having such an extension on String allows you to use localized version of strings like this:

A few more tips on extending String

If you have a large app, your Strings+Localized.swift file can become large and unreadable. You can divide strings into multiple extension blocks and annotate them using //MARK::

You could even create a file for each screen, e.g. Strings+Login, Strings+Welcome.swift, but be aware that in rapid development it can be a hinder task to do and maintaining multiple files could become even trickier.

One more thing to note is that Strings defined in the described way are static strings. Your app should be relaunched after changing language in iOS Settings app. If not, relaunch it by yourself in order to see changes. It can also have a memory overhead, since we initialize all strings at once, not at the time they’re needed.

Resources

6 Comments

    • Maciej Piotrowski

      Thanks for sharing! SwiftGen addresses issue that static variables in String extension cannot – associated values:
      let nbApples = tr(.ApplesCount(5))// -> "You have 5 apples"

  1. Cesar

    “It can also have a memory overhead, since we initialize all strings at once, not at the time they’re needed.”

    Solution:
    Instead of using static constants you can use computed variables in the String extension.

    i.e:

    extension String {
    static var hello: String {
    return NSLocalizedString(“Hello”)
    }
    }

    implementation keeps the same.

Leave a Reply


*