Mastering Swift and SwiftUI

Insights, Tips, and Tutorials for iOS Developers

How to Localize Text in SwiftUI

Published on Aug 26, 2024

Get a quick glimpse of how Tiny Currency simplifies currency conversion with up to date rates, multi-currency support, and easy-to-use widgets. Perfect for on-the-go use, our app ensures you're always prepared, no matter where your travels take you.

Why Localization Matters

Before diving into the how-to, let’s quickly touch on why localization is so important. At its core, localization is about adapting your app to different languages and cultural contexts. This not only includes translating the text but also adjusting formatting for dates, times, numbers, and even colors or images based on cultural relevance. By localizing your app, you’re making it more accessible and appealing to a broader audience, which can significantly impact your app’s success.

Seamless Integration: Localization Built Right into SwiftUI

One of the standout features of SwiftUI is how effortlessly it integrates localization into your app’s existing views. Unlike older frameworks where you might need to juggle multiple files or write additional boilerplate code, SwiftUI handles localization almost transparently. This means you can focus more on your app’s logic and design, and less on managing localized content.

Let's take the first example: SwiftUI's Text

import SwiftUI

struct ContentView: View {
    var body: some View {
        VStack {
            Text("This text is localized for free.")
            Text("And so is this one!")
        }
    }
}

The default initializer for Text in this case is init(_:tableName:bundle:comment:). It uses a LocalizedStringKey instead of a regular string for built-in localization.

Dynamic Data

What if you want to provide data along a raw string? Let's use dates as an example. SwiftUI makes this easy to do:

import SwiftUI

struct ContentView: View {
    var body: some View {
        Text("The current date is \(Date(), format: .dateTime)")
    }
}

As you can see, LocalizedStringKey conforms to ExpressibleByStringInterpolation which allows us to interpolate values within the key, which automatically gets picked up by Xcode when exporting localizations.

This interpolation specifically uses the appendInterpolation(_:format:) function that allows for the format to be specified. In this case, we use .dateTime.

Take a look at all the possible formats that you can use to interpolate all kinds of data.

Custom Views

So now that we know built in views use LocalizedStringKey, what if we want to have localization in a custom view? Documentation suggests we should not be using LocalizedStringKey within our own custom views, so to add support for this, Apple has introduced LocalizedStringResource

import SwiftUI

struct ContentView: View {
    var title: LocalizedStringResource = "Default Title"
    
    var body: some View {
        Text(title)
    }
}

The nice thing here is that LocalizedStringResource implements ExpressibleByStringLiteral which allows us to specify a default string easily.

⚠️ Note that when localizing text inside a Swift Packages, you have to ensure that the resource is looking for the string in the right module. You should specify the bundle whether you use LocalizedStringKey or LocalizedStringResource:

import SwiftUI

struct ContentView: View {
    var title = LocalizedStringResource("Default Title", bundle: .module)
    
    var body: some View {
        VStack {
            Text(title)
            Text("Localized subtitle", bundle: .module)
        }
    }
}

By leveraging SwiftUI’s built-in localization features, you can effortlessly create apps that are both globally accessible and culturally relevant. Whether you’re working with static text, dynamic data, or custom views, SwiftUI provides the tools you need to deliver a seamless localized experience with minimal effort. Start localizing your app today, and reach a broader audience with ease.