Logo for tanaschita.com

Working with String Catalogs in iOS projects

Practical tips, limitations, and best practices for localization with .xcstrings files.

16 Mar 2026 · 6 min read

Localization is an essential part of many iOS apps. Prior to String Catalogs, developers managed localized strings using Localizable.strings and Localizable.stringsdict files. While this approach works well, it requires manual maintenance and can easily lead to missing or outdated localization keys.

String Catalogs simplify this workflow by integrating localization management directly into Xcode. In this article, we'll look at how String Catalogs work in practice. Let's jump right in.

Sponsorship logo
Architecture & Design Patterns for iOS
This book is a practical guide to essential architectural principles and design patterns for iOS development. It covers strategies for building maintainable apps with Swift and SwiftUI, including dependency injection, navigation, common patterns, and modularization.
LEARN MORE

What is a String Catalog?

A String Catalog is a file with the extension .xcstrings, typically named Localizable.xcstrings.

Contrary to Localizable.strings and Localizable.stringdict files, a String Catalog manages all translations in a single structured file. Inside Xcode, the catalog provides a dedicated editor where we can view and manage all localized strings across supported languages.

String catalog

Internally, a String Catalog is stored as JSON. A simplified example might look like this:

{
"sourceLanguage": "en",
"strings": {
"loginButton.title": {
"localizations": {
"de": {
"stringUnit": {
"state": "translated",
"value": "Einloggen"
}
},
"en": {
"stringUnit": {
"state": "translated",
"value": "Login"
}
}
}
}
},
"version": "1.0"
}

Automatic detection of localizable strings

One of the most convenient features of String Catalogs is Xcode's automatic detection of localized strings.

Whenever the project is built, Xcode scans the codebase for known localization APIs and automatically adds detected keys to the String Catalog.

For example, when using SwiftUI's Text view with Text("loginButton.title"), Xcode automatically creates a new entry for us.

Once the entry is created, translations can be added directly in the catalog editor.

For cases where localized strings need to be passed around in code, the LocalizedStringResource type can be used to maintain automatic detection.

Manual management of localized strings

In some cases, Xcode cannot detect keys, for example when they are constructed dynamically:

Text("loginButton." + state)

Since Xcode cannot determine the final key during compilation, these strings will not appear automatically in the String Catalog. In such cases, entries must be added manually.

When we switch an entry to manual management, Xcode will no longer modify or remove it automatically.

Manage String Catalog entries manually
Managing String Catalog entries manually

Manual management can be useful when:

  • localization keys are generated dynamically
  • strings are shared across multiple modules
  • keys are intentionally kept even if not currently referenced in code

Understanding String Catalog states

String Catalog entries can appear in different states depending on how they are used in the project. For example:

  • new - the string was detected but has not yet been translated.
  • needs_review - indicates that a translation should be checked again.
  • stale - the string is no longer referenced in the code.
  • translated - all required translations are available.

When Xcode marks an entry as stale, it means the key is no longer detected in the codebase.

Stale state
Stale state

At this point, the entry can either be removed or switched to manual management.

The needs_review state can be set manually to indicate that a translation should be checked again, for example when the source text changes:

Mark for review
Mark a string for review

Practical tip: renaming localization keys

When working with localization keys, it's common that naming conventions evolve over time. For example, we might decide to rename a key like loginButton.title to something more structured such as login.button.title.

A straightforward approach would be to simply update the key in the codebase:

Text("login.button.title")

However, when doing this, Xcode treats the new key as a completely new entry. The old key will be marked as stale, while the new key appears as new.

This means all translations associated with the old key would need to be copied manually to the new one.

A more practical approach is to rename the key directly in the String Catalog editor in Xcode. When renaming a key from within the catalog, Xcode updates the references in the codebase automatically while keeping the existing translations intact:

Change key
Refactoring keys

This allows us to refactor localization keys without losing translations or creating duplicate entries.

Sponsorship logo
Preparing for a technical iOS job interview
Preparing for a technical iOS Job Interview with over 300 questions & answers. Covering Swift & Objective-C, SwiftUI & UIKit, Combine, HTTP Networking, iOS File System, Core Data, Concurrency with async/await, Security, Automated Testing, Dependency Management, AI & Machine Learning and more.
LEARN MORE
Sponsorship logo
Architecture & Design Patterns for iOS
This book is a practical guide to essential architectural principles and design patterns for iOS development. It covers strategies for building maintainable apps with Swift and SwiftUI, including dependency injection, navigation, common patterns, and modularization.
LEARN MORE
Sponsorship logo
Become a sponsor of tanaschita.com
By publishing an article on different iOS topics every week, tanaschita.com is constantly growing in the developer community and may provide a great audience for you as a sponsor.
CLICK TO LEARN MORE

Newsletter

Image of a reading marmot
Subscribe

Like to support my work?

Say hi

Related tags

Articles with related topics

localization

swift

ios

Migrating to String Catalogs in iOS

Learn about migration strategies from Localizable.strings to .xcstrings.

23 Mar 2026 · 3 min read

Latest articles and tips

© 2026 tanaschita.com

Privacy policy

Impressum