Have you ever found yourself in the situation that you worked on an app for quiet a while and the project evolved more and more from what was once more of a prototype? Have you forgotten or just haven’t had the time to plan every part in advance? Have you or your client then noticed, that it would be nice to publish your app in various languages?

Have you then spent hours searching for all the strings in your project and replace them with localized strings? Well, if you have (just like me in my last project) or even if not, this article might be interesting for your (especially if you are just about to start a new app).

Strings are bad

Let me tell you the story about how I got rid of almost every string in my project while at the same time make localization as easy as pie. But first, why are strings bad? Well, thats an easy question to answer: because you have no way to check whatever is inside the string.

This is especially bad in some cases, where you have to rely on that whatever is in a string is actually correct and when you use a certain string in multiple locations. Its easy to create typos when writing the same text over and over again. Like when using strings as segue or cell identifiers. Raise your hand if your app crashed at least once because a identifier had a typo. ✋

It is easy to hard code a string here and there but at some point, when you are writing the same text over and over again, it’s time to refactor. Then we put the string in a constant somewhere in our class and get autocompletion. This is okay for stuff like identifiers even though there are better ways.

But what if we need some text which gets displayed to the user in multiple locations in our app? Its a bad idea to have the same string constant hanging around in multiple classes.

String extension to the rescue

The logical consequence is to create some sort of constants file which is globally valid. I actually don’t like putting my strings in such a file. I rather use an extension on String itself. This way, it’s even easier to use my localized string (more about localization/i18n in a minute).

I mean, lets compare two examples. A typical app constants file version vs a String extension:

//First off with the constants. Everybody has created or seen a struct like this, right? 
struct MyConstants {
    static let myString = "My String"
}

//And heres the better choice, a simple String extension
extension String {
    static let myString = "My String"
}

Sure, you could replace struct with enum so it’s not instantiable but then you’d also had to have at least one case in the enum. But that is absolutely not my point. My point is the type inheritance of the Swift compiler. Lets look at an example which makes the advantage of the String extension pretty obvious:

let myConstantString: String = MyConstants.myString
let myStringString: String = .myString

Woa, we can assign the string without explicitly calling the struct/enum/class or whatever. Isn’t that awesome? I like how short and clean my code suddenly becomes. I constantly assign meaningful default values to labels. I define them in one place and can be sure to never make typos again. Well except in the String extension of course but at least I now only have to look in one place.

Making your strings localizable and supporting i18n

At some point, internationalization becomes a topic of almost every app. With our strings all in one place, its easier than never before to support i18n. Want to see how easy? Let me show you! First we define another nice extension on String to get localized strings:

var localized: String {
    return NSLocalizedString(self, tableName: "Strings", bundle: Bundle.main, value: "", comment: "")
}

Next, just go through your String extension file and add .localized to each of the strings:

extension String {
    static let myString = "My String".localized
}

Can it be easier? I don’t know but if you do, I’d really love to learn about it as well so feel free to leave a comment. Cheers ✌️