Apple's supported way is the per-app language in Settings (iOS 13 and later), which your app can open with `UIApplication.openSettingsURLString`. Writing to the `AppleLanguages` default needs a relaunch, and loading a specific `.lproj` bundle at runtime means re-rendering the UI yourself.
Interpolate the count into one string such as `\(count) items`, then select the key in the String Catalog and choose Vary by Plural; Xcode adds the plural categories each language needs. Before Xcode 15, the same forms go into a `.stringsdict` file.
Pass string literals to `Text`, `Button`, `Label` and similar views; they are `LocalizedStringKey` values that SwiftUI looks up in the String Catalog automatically. A `String` variable is shown as is unless you wrap it in `LocalizedStringKey`, and `Text(verbatim:)` opts out of localization.
Localize the `CFBundleDisplayName` and `CFBundleName` Info.plist keys, either in an `InfoPlist.strings` file inside each `.lproj` folder or, in Xcode 15 and later, in an `InfoPlist.xcstrings` String Catalog. The App Store name is localized separately in App Store Connect.
The fallback is the development language, stored as `CFBundleDevelopmentRegion` in Info.plist and as `developmentRegion` in the Xcode project. iOS uses it when none of the user's preferred languages match the app's localizations, and you change it by editing `developmentRegion` in `project.pbxproj`.
Interpolate the value inside `String(localized:)` (iOS 15 and later) or a SwiftUI `Text` literal; Xcode stores the key with a `%@` or `%lld` placeholder that translators keep. On older targets, combine `NSLocalizedString` with `String.localizedStringWithFormat`.
The code `es` is Spanish with no region and `es-419` is Latin American Spanish; 419 is the UN M.49 code for Latin America and the Caribbean. A user set to Spanish (Mexico) gets the `es-419` localization when the app has it and `es` otherwise, while a user set to Spanish (Spain) gets `es`.
Usually the file is not in the right `.lproj` folder or target, a single syntax error disables the whole table, or the app runs in a language you did not expect. Check the built app bundle, run `plutil -lint` on the file, and set the App Language in the scheme.