My app has been Japanese-only since launch. I added English last week. I thought it would be a translation job. It was mostly an archaeology job.
Auto-extraction picked up 51 strings. A manual pass through the same 15 files found 159. Here's where the other 108 were hiding.
The big one: anything that isn't a \`LocalizedStringKey\` parameter just doesn't get extracted. \`Text("...")\` is fine. \`String\` variables, computed properties, switch statements returning \`String\`, notification bodies, \`errorDescription\`, none of it. Most of my misses were my own custom views, \`FeatureRow(title: String, ...)\` and friends. I wrapped the call sites in \`String(localized:)\` instead of changing the view signatures, which kept the diff small.
Check this before you start: my \`developmentRegion\` was still \`en\` from the Xcode template even though every literal in the project was Japanese. So the catalog happily registered my Japanese as English. You can't fix that in the UI, you have to edit \`project.pbxproj\`.
Permission strings were their own thing. They live in \`INFOPLIST_KEY_\*\` build settings, not in code, so nothing I did to the catalog touched them. Bonus discovery: past me had jammed English and Japanese into one string with a \`\\n\` between them, so every user saw both languages regardless of their device. Had been shipping that for months.
Then there was this:
formatter.dateFormat = "HH:mm 撮影"
A Japanese word inside a format string. Can't swap that for English because English wants a different shape ("Shot at 14:30"). Had to pull the formatter apart and rebuild the display string. Same deal with \`displayPrice + " / 月"\`.
The one that actually cost me a round of testing was keys that already existed. "Library" was a nav title (extracted, translated, fine) and also a plain \`String\` in my tutorial data (not extracted). My audit saw the key was already in the catalog and moved on. So I had a fully English UI with a tutorial popping up in Japanese. Same thing in a comparison table. Catalog coverage is not call site coverage.
One choice that will probably annoy people here: I used the Japanese source text as the key instead of \`onboarding.title\` style keys. The Japanese build was already live and I didn't want to touch every call site. Downside is that editing Japanese copy now means editing a key. For a solo project I'll take that.
Edit Scheme > Run > Options > App Language launches in English without changing your device language. Saved me a lot of time. Doesn't affect permission dialogs though, those follow the system language.
Two weeks of early mornings, and most of it was reading my own code rather than writing anything.