Swift Localization in 2025: Best Practices You Couldn’t Use Before

String Catalogs improved localization but introduced new challenges. This article explores how to regain structure and efficiency with modern best practices and a new open-source tool that could change the way you localize.

Swift Localization in 2025: Best Practices You Couldn’t Use Before
Photo by Greg Rosenke / Unsplash

The Evolution of iOS Localization

To understand how far localization has come—and where it still falls short—let’s take a quick look back: At the pre-String Catalogs era, developers relied on a combination of .strings and .stringsdict files, organized in language-specific folders like en.lproj. This system, while functional, had several drawbacks:

  1. Missing safety checks for unused or missing translations
  2. Manual synchronization needed between different language files
  3. No built-in support for extracting strings from code

Tools like SwiftGen and BartyCrouch emerged to address these issues, providing type safety and automated extraction. And the community established best practices around using semantic keys (e.g., "Onboarding.Page1.title") to provide context for translators and group related strings together.

String Catalogs: A Game-Changer with Trade-offs

String Catalogs introduced by Apple in 2023 solved several long-standing issues:

Automatic key extraction from code
✅ Built-in safety checks for missing translations
✅ Visual progress tracking in Xcode
Unified file format for all languages
Backward compatibility with older iOS versions

However, Apple's recommended approach of using English strings as keys, while improving readability in code, introduced new challenges:

❌ Related strings are scattered alphabetically
❌ Reduced context for translators
❌ No grouping by feature or screen

The lack of grouping in String Catalogs is not helpful while translating.

Just as importantly, there's a significant gap in the iOS development ecosystem around localization that mirrors where we were with icons before SF Symbols. Before SF Symbols, every developer had to create or source their own icons, leading to inconsistent experiences across apps. SF Symbols solved this by providing a standardized, comprehensive set of icons that ensure consistency and save tremendous development time.

The localization space desperately needs a similar solution. Every app needs common UI strings like "Save," "Cancel," "Done," "Privacy Policy," or "Terms and Conditions" – and these should be consistent across apps just like icons are. Users benefit from this consistency in the same way they benefit from consistent iconography. Yet currently, each developer must translate these common UI elements independently, leading to varying translations for the same concepts across different apps in different languages.

Enter TranslateKit: The Missing Piece

The open-source TranslateKit SDK bridges these gaps, offering a comprehensive solution that maintains best practices while fully embracing the benefits of String Catalogs. Just as SF Symbols revolutionized icon usage in iOS apps, this new Swift package aims to do the same for localization.

1. Semantic Key Generation Without the Hassle

The #tk macro brings back semantic keys while keeping code clean and readable:

struct OnboardingView: View {
  var body: some View {
    // Generates key: OnboardingView.Body.welcomeToMyApp
    Text(#tk("Welcome to MyApp"))
  }
}

This approach:

  • Automatically generates semantic keys based on code context
  • Preserves code readability
  • Provides essential context for translators
  • Groups related strings together in String Catalogs
Auto-generated semantic keys, naturally grouping related strings together.

And all you need to write is #tk() around your String literals. Super simple!

2. Pre-localized Common UI Elements

Just as SF Symbols standardized icon usage, we need consistency in UI text. TranslateKit provides over 2,000 strings pre-localized to all 40 languages supported by Apple in the iOS operating system.

They are divided into 4 categories, making it easy to discover what you need:

// Actions
Button(TK.Action.save) { saveData() }
// => en: "Save", de: "Sichern", etc.

// Labels
Text(TK.Label.privacyPolicy)
// => en: "Privacy Policy", de: "Sichern", etc.

// Messages
Text(TK.Message.areYouSure)
// => en: "Privacy Policy", de: "Datenschutzerklärung", etc.

// Placeholders
ProgressView(TK.Placeholder.loadingDots)
// => en: "Loading…", de: "Laden…", etc.

Benefits:

  • Matches system UI translations from Apple (Consistency)
  • Ensures professional quality for common UI elements (Accuracy)
  • Reduces localization overhead (save Time & Money)

3. Context-Aware Translations

Modern localization isn't just about translating words—it's about understanding context. While automatic key generation helps with this in 90% of the cases, in some cases you might need to additionally specify the optional c parameter:

struct DocumentView: View {
    let fileName: String
    
    var body: some View {
        Button(#tk("Delete '\(fileName)'?",
                   c: "Example: Delete 'MyStats.csv'?")) {
            handleDelete()
        }
    }
}

This comment parameter is most commonly needed when you have dynamic data in your string like in the example above. It's important to always provide typical sample data in the comment to make it clear. Otherwise translators might not know how to translate properly.

What's Next?

This article covered how TranslateKit SDK modernizes the core localization workflow. If you're interested in more advanced topics like pluralization, formatters & more, subscribe to my YouTube channel to signal your interest in more detailed videos:

FlineDev
Videos about Swift & iOS Development produced by Cihat Gündüz,📱Indie iOS Developer, 🎬Content Creator for 👨🏻‍💻Developers, incurable 🇯🇵Japan and 🪄Harry Potter fan.
TranslateKit SDK works perfectly together with TranslateKit for Mac, an accurate, AI-powered translation tool to localize the rest of your app! It's super fast & affordable, try free now to reach more users.
👨‍💻
Want to Connect?
Follow me on 🦋 Bluesky, 🐦 Twitter (X), and 🦣 Mastodon.