Framework Reference
Complete public API of the ProjectLocale iOS SDK. All types live in the ProjectLocale module. Import it with import ProjectLocale.
Configuration
Initialize the SDK. Must be called once at app launch before any other method.
apiKey: String— your project API key (pl_...), found in project settingsserverURL: URL— server URL, e.g.https://p-locale.euenvironment: String = "prod"— target environment:dev,qa, orprodappVersion: String? = nil— app version for per-version translations; passCFBundleShortVersionStringfallbackBundle: Bundle = .main— bundle containing fallback.stringsfileslogLevel: LogLevel = .warning— logging verbositylogHandler: LogHandler = defaultLogHandler— custom log output handlerrealtimeEnabled: Bool = false— enable WebSocket connection for instant translation updates pushed from the server
Alternative initializer using a Configuration struct. Same parameters as above, plus session: URLSession and storageDirectory: URL?.
import ProjectLocale try L10n.configure( apiKey: "pl_your_api_key", serverURL: URL(string: "https://p-locale.eu")!, environment: "prod", appVersion: Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String )
Syncing Translations
Fetch project metadata from the server: available languages, environments, and per-version configuration. Usually the first call on launch.
Convenience wrapper: calls projectInfo(), then fetches translations for all languages in parallel. Returns the list of synced locale codes. Removes cached locales that are no longer in the project.
Download translations for a specific locale. Returns true if new data was applied. Uses delta sync — only changed keys are transferred.
Check for and apply updates for the given locale (defaults to current language). Returns true if translations were updated.
// Sync all languages at once let synced = try await L10n.syncAll() // Or sync a specific locale try await L10n.fetch(locale: "de")
Using Translations
Resolve a translation key. Keys use the format namespace/key_name. Returns the translation for the current language, or the default value if the key is not found.
key: String— full key, e.g."common/welcome_title"default: String = ""— fallback if the key is missing; if empty, the key itself is returnedtable: String? = nil— optional table override (defaults to namespace from key)
SwiftUI view that displays a translated string. Automatically updates when translations change. Available on iOS 15+.
// SwiftUI L10nText("common/welcome_title", default: "Welcome") // Imperative (UIKit, ViewModels, etc.) let title = L10n.string("common/welcome_title", default: "Welcome")
Language Management
Switch the active language. Triggers L10n.observer so any SwiftUI view observing it will refresh automatically.
The currently active language code (BCP-47). Defaults to the device's preferred language.
List of locale codes for which translations are currently cached locally.
Returns true if at least one locale has cached translations from a previous session.
Reactivity (Combine)
A shared ObservableObject that publishes a revision counter every time translations change — whether from a network sync, language switch, or a real-time WebSocket push. Use @ObservedObject in SwiftUI to get automatic UI refresh.
struct MyView: View { @ObservedObject private var observer = L10n.observer var body: some View { let _ = observer.revision Text(L10n.string("welcome_title", default: "Welcome")) } }
Real-Time Updates (WebSocket)
When enabled, the SDK opens a WebSocket connection to the server. Translation changes made in the web UI are pushed to the device instantly — no polling or manual sync required. The connection auto-reconnects with exponential backoff if interrupted.
Updates arrive through the same L10n.observer pipeline, so any SwiftUI view already using @ObservedObject will refresh automatically.
try L10n.configure( apiKey: "pl_...", serverURL: URL(string: "https://p-locale.eu")!, realtimeEnabled: true )
Diagnostics
Returns the last-known revision for each cached locale. Useful for debugging sync state. Keys are BCP-47 locale codes.
Types
Project metadata returned by projectInfo().
slug: String— project URL slugname: String— project display namesourceLanguage: String— source language codetargetLanguages: [String]— target language codeslanguages: [String]— all languages (source + target)environments: [String]— available environmentsenvironmentsVersions: [EnvironmentVersions]?— per-environment version metadatalanguages(for:appVersion:) → [String]?— resolve languages for a specific environment and version
Logging verbosity levels: .debug, .info, .warning, .error, .critical, .off.
Errors thrown by SDK methods.
.notConfigured—L10n.configure()was not called.network(underlying:)— network request failed.http(status:body:)— server returned a non-success HTTP status.invalidArchive(reason:)— translation bundle is malformed.invalidManifest(reason:)— manifest data is invalid
Platform Guide
Step-by-step guide to using the Project Locale web platform — from creating a project to delivering translations to your app.
Account & Registration
Create an account
Go to p-locale.eu and click Sign up free. Enter your email, username, and password. A verification email will be sent — click the link to activate your account.
Choose a plan
The free plan includes 1 project and 2 languages. Upgrade anytime from your Profile page to unlock more projects, languages, team members, and AI translations.
Profile settings
In Profile you can change your password, update your email, manage your subscription, and leave projects you've been invited to.
Projects
Create a project
Click New project on the dashboard. Enter a name, select a source language, and add target languages. The project slug is generated automatically and used in the API.
API key
Each project has a unique API key displayed in the project settings (Edit page). This key is used in the SDK's L10n.configure(apiKey:). You can rotate the key at any time — the old key will stop working immediately.
Project settings
From the project edit page you can rename the project, change source/target languages, and delete the project. Deleting a project removes all environments, versions, keys, and translations permanently.
Environments & Versions
Environments
Environments separate translations for different stages: dev, qa, prod. Each environment has its own set of app versions. The SDK connects to the environment specified in L10n.configure(environment:).
App versions
Inside each environment, you create app versions that match your app releases (e.g. 1.0, 2.0). Each version has its own set of translations, languages, and revision counter. The SDK sends appVersion to get translations for the matching version.
Per-version languages
You can configure which target languages are available for each version. This lets you add a new language to v2.0 without affecting v1.0.
Namespaces & Keys
Namespaces
Namespaces group related keys together (e.g. common, settings, onboarding). Each version starts with a common namespace. You can create more from the project page.
Creating keys
Click Add key on the project page. Enter the key name and select a namespace. The full key path used in code is namespace/key_name.
Translation editor
Click any key to open the editor. You'll see all target languages side by side. Edit translations inline — changes are saved immediately. Each translation has a status: draft, translated, reviewed, or approved.
Translation statuses
Draft — empty or initial. Translated — text entered. Reviewed — checked by a reviewer. Approved — ready for delivery. Only approved translations are delivered to devices via the SDK.
Import & Export
Import .strings
Click Import on the project page. Upload a .strings file, select the target language and namespace. Existing keys will be updated; new keys will be created automatically.
Export .strings
Click Export to download translations as a .strings file. Select the language and namespace to export. The file can be used directly in Xcode.
AI Translation
Translate a single key
In the translation editor, click the AI button next to any language field. The system will generate a translation based on the source text. Review and approve before it goes live.
Batch translate
When you add a new language to a version, you can use AI Batch Translate to translate all existing keys at once. This is available on paid plans.
SDK Integration
Install the SDK
Swift Package Manager (recommended): In Xcode, go to File → Add Package Dependencies, enter https://github.com/biometricid/p-locale.eu, select Up to Next Major Version (1.1.0), and click Add Package.
Manual: Go to the SDK page to download ProjectLocale.xcframework. Drag it into your Xcode project with Do Not Embed (static library).
Configure and sync
Call L10n.configure() in your app's init() with your API key and server URL. Then call L10n.syncAll() to download translations. See the Framework Reference above for full API details.
How delivery works
The SDK caches translations locally. On each app launch, it sends a revision number to the server. If translations changed, only the diff is downloaded (delta sync). If nothing changed, the server responds with 304 Not Modified — zero data transfer. Translations are available offline from cache.