How traditional iOS localization works
A conventional iOS app ships localized resources inside the app bundle. Localizable.strings stores key-value copy, while string catalogs such as .xcstrings organize translations and variations in Xcode. SwiftUI's localized text APIs and Foundation resolve those resources for the active locale.
Bundled resources are dependable because they are installed with the binary and work offline. Their release boundary is also the app binary: correcting bundled copy normally requires a new build and App Store release. Assets, layouts, and executable behavior still belong in that traditional release process.
Can iOS translations be updated without an App Store release?
Yes, for text that the application intentionally resolves from a remote localization layer. An OTA client can fetch a published translation artifact, validate it, cache it, and use it on later lookups. This should complement—not remove—the translations bundled with the app.
OTA localization changes localization data. It should not be used to deliver executable code, new layouts, or behavior that belongs in an reviewed app release.
Install the GoLocalise Swift package
Add the public package in Xcode with File → Add Package Dependencies, or declare it in a Swift package. Version 1.0.0 supports iOS 15+ and macOS 12+.
dependencies: [
.package(
url: "https://github.com/abdallahnh/golocalise-swift.git",
from: "1.0.0"
)
]Configure an offline-safe client
Use a public gl_sdk_ credential scoped to the project and environment. The SDK loads persistent cache, refreshes in the background, and resolves each lookup synchronously from OTA memory, bundled translations, the caller fallback, then the key.
import GoLocalise
let bundled = DictionaryBundledTranslations([
"en": ["common": ["welcome": "Welcome"]],
"ar": ["common": ["welcome": "مرحباً"]],
])
let client = GoLocaliseClient(configuration: try GoLocaliseConfiguration(
baseURL: URL(string: "https://api.golocalise.me")!,
token: "gl_sdk_REPLACE_ME",
projectId: "PROJECT_ID",
environment: "production",
locale: "en",
cache: try FileCacheAdapter(directory: cacheDirectory),
bundled: bundled
))
Task { await client.initialize() }
let title = client.translation(
for: "welcome",
namespace: "common",
fallback: "Welcome"
)Publishing, cache safety, and rollback
GoLocalise publishes approved content as an immutable environment release. The Swift SDK checks manifest scope, release order, artifact origin, byte size, and SHA-256 before atomically replacing its cache. A failed refresh keeps the last-known-good cache and bundled baseline available.
A rollback does not rewrite an earlier release. It creates a new release from historical content, preserving an auditable version sequence. Read the deeper OTA engineering guide for the complete fetch and fallback path.
iOS localization implementation checklist
- Keep complete source-language and critical fallback copy bundled.
- Use stable semantic keys rather than visible English sentences.
- Test missing keys, first launch offline, corrupt cache, and timeout paths.
- Exercise long translations, Dynamic Type, plurals, and RTL layouts.
- Publish to Development and Staging before creating a Production release.
- Never embed an organization API secret in the application.