#NoteToForget
— Written by someone who’s shipped 4+ localized apps…
(Still need this post again later 😅)
🧩 The Essentials
Let’s be honest.We’ve all hardcoded strings in Swift like this:
let message = "This field cannot be left empty”;
Tempting? Absolutely.
Practical? Sure — until your PM casually drops:
“Can we support Indonesian 🇮🇩, German 🇩🇪, and Klingon by next sprint?” 🫠
Text(message)
At a glance, they look harmless — just strings.
But they’re not just any strings — they’re UI text your users will read, and they’re locked to one language.
But they’re not just any strings — they’re UI text your users will read, and they’re locked to one language.
Practical? Sure — until your PM casually drops:
“Can we support Indonesian 🇮🇩, German 🇩🇪, and Klingon by next sprint?” 🫠
❌ Why It Doesn’t Cut It
⦿ Scattered Strings – Text is all over the place, making updates and translations a mess.
⦿ No Tooling Support – You miss out on Xcode’s built-in localization tools.⦿ Hard to Scale – Good luck adding languages or managing translations later.
✅ The Better Way
Use NSLocalizedString() and .strings files like a civilized iOS developer.
It keeps your code clean, makes your app translatable, and lets Apple do what it does best: hide complexity with keywords.
🛠️ Environment
◼ Xcode: 16.2
◼ Swift: 5.10🚀 Workflow That Just Works™
1. Add Localizations
1.1 Add Localizations to Your Project☞ Go to project navigator 〉 Project 〉Info 〉Localization
☞ Click the ➕ 〉Add: Indonesian, German
1.2 Create Localizable.strings Files
☞ Right-click your project root 〉 New File 〉Resource 〉Strings File 〉 Name it: Localizable.strings
☞ Click Localizable.string 〉File Inspector 〉Localization 〉Check all languages: German and Indonesian
2. Add Translations
▪️Localizable (English)
"alert_empty_field" = "This field cannot be left empty”;
"alert_empty_field" = "This field cannot be left empty”;
▪️Localizable (Indonesian)
"alert_empty_field" = "Bagian ini tidak boleh kosong”;
▪️Localizable (German)
"alert_empty_field" = "Dieses Feld darf nicht leer sein”;
3. Implement Localization in Code
3.1 Simple Version
let message = NSLocalizedString("alert_empty_field", comment: "”)Text(message)
3.2 Cleaner Syntax with helper
extension String {
var localized: String {
NSLocalizedString(self, comment: "")
}
}
extension String {
var localized: String {
NSLocalizedString(self, comment: "")
}
}
Usage:
let message =
"alert_empty_field".localized
Text(message)
3.3 Modular Approach
The modular version using `Bundle(identifier:)` is generally preferred for multi-module apps, as it allows you to specify which localization bundle to look in rather than relying on the main app bundle.
extension String {
public func localized(identifier: String -> String {
let bundle = Bundle(identifier: identifier) ?? .main
return bundle.localizedString(forKey: self, value: nil, table: nil)
}
}
Usage:
let message = "alert_empty_field".localized(identifier: “com.enjelhutasoit.App.ModuleName")
Text(message)
🧪 Testing Your Setup
On Simulator
☞ Go to Product 〉Scheme 〉 Edit Scheme
☞ Open Run 〉Options
☞ Set App Language and App Region to test (e.g., Indonesian, German)
☞ Hit Run — your app will launch in that locale.
On Device
☞ Open Settings 〉 General 〉 Language & Region
☞ Change device language to your target language
☞ Relaunch the app to see live localization
If Changes Don't Appear
▪️Clean your build (Cmd+Shift+K)
▪️Restart Xcode
▪️Double-check you localized the .strings file
▪️Restart Xcode
▪️Double-check you localized the .strings file
📌 Key Takeaways
✅ App feels pro and scalable
✅ Fallbacks to English are automatic, no trauma needed
✅ Your future self will love you (again).
✅ Fallbacks to English are automatic, no trauma needed
✅ Your future self will love you (again).
🧠 Final Note
Yes, you’ve done this before.
Yes, you forgot the steps.That’s why this blog post exists: not to teach you something new — just to save your future self from Googling it again.
You’re welcome.
— #NoteToForget