Skip to content
better-i18n.com
本页内容

I18nConfig #

Configuration struct passed to BetterI18n. All properties except project and defaultLocale are optional.

PropertyTypeRequiredDefaultDescription
projectStringProject identifier from the dashboard (e.g. "my-org/my-app")
defaultLocaleStringFallback locale when no preference is stored (e.g. "en")
appGroupIdentifierString?nilApp Group ID for shared storage with widget extensions
cdnBaseURLStringBetterI18n CDNCustom CDN base URL for self-hosted translations
Swift
let config = I18nConfig(
    projectId: "my-org/my-app",
    defaultLocale: "en",
    appGroupIdentifier: "group.com.mycompany.myapp"
)

I18nProvider #

A SwiftUI view that initializes an I18nStore and injects it into the environment.

Swift
struct I18nProvider<Content: View>: View {
    init(core: BetterI18n, @ViewBuilder content: () -> Content)
}
ParameterTypeDescription
coreBetterI18nConfigured SDK instance
content() -> ContentRoot view builder

I18nProvider creates I18nStore as a @StateObject and calls store.load() via .task on first appear. It exposes the store as an @EnvironmentObject to all descendant views.


I18nStore #

@MainActor @ObservableObject — the reactive state container for translations.

Published Properties #

PropertyTypeDescription
localeStringCurrently active locale code
isLoadedBooltrue after Phase 1 (storage read) completes
isRefreshingBooltrue while a CDN fetch is in progress
errorError?Last fetch error, if any

Methods #

load()

Starts the two-phase load sequence:

  1. Phase 1 — reads cached translations from storage, sets isLoaded = true
  2. Phase 2 — fetches fresh translations from CDN in the background, updates silently
Swift
await store.load()

Called automatically by I18nProvider. You only need to call this manually if you create I18nStore without I18nProvider.

setLocale(_:)

Changes the active locale, saves the preference to storage, and re-fetches translations.

Swift
await store.setLocale("tr")

t(_:_:)

Translates a key with optional interpolation variables.

Swift
store.t("home.welcome")                        // → "Welcome"
store.t("home.greeting", ["name": "Osman"])    // → "Hello, Osman!"

Returns the key string unchanged if no translation is found.


BetterI18n #

The core SDK class. Use this directly when you need fine-grained control or when building non-SwiftUI targets (widgets, command-line tools, etc.).

Initializer #

Swift
BetterI18n(config: I18nConfig)

Methods #

MethodReturnsDescription
load()asyncTwo-phase load: storage then CDN
setLocale(_:)asyncChange locale + persist preference
detectLocaleFromStorageOnly()async -> StringRead saved locale preference without network
getTranslatorFromStorageOnly(locale:)async -> Translator?Return a Translator from cache only, no CDN call
translator(for locale: String)Translator?Synchronous access to loaded translator

Storage-only API

The storage-only methods are designed for WidgetKit extensions where network calls during timeline generation are unreliable. They read from UserDefaults synchronously and return nil if nothing is cached.

Swift
let locale = await i18n.detectLocaleFromStorageOnly()
let t = await i18n.getTranslatorFromStorageOnly(locale: locale)
let title = t?("widget.title") ?? "My App"

Storage #

BetterI18n uses a TranslationStorage protocol to abstract where translations are persisted.

TranslationStorage Protocol #

Swift
public protocol TranslationStorage {
    func getString(forKey key: String) -> String?
    func setString(_ value: String, forKey key: String)
}

Built-in Implementations #

TypeBackendUse case
UserDefaultsStorageUserDefaults.standardStandard app storage (default)
AppGroupStorageUserDefaults(suiteName:)Shared storage with widget extensions

AppGroupStorage is selected automatically when I18nConfig.appGroupIdentifier is set.


Translator #

Translator is a function type that accepts a key and optional variables:

Swift
public typealias Translator = (_ key: String, _ variables: [String: String]?) -> String?

It's returned by BetterI18n.getTranslatorFromStorageOnly(locale:) and used internally by I18nStore.t().

callAsFunction patterns #

Swift
// Basic translation
translator("home.title")

// With interpolation
translator("home.greeting", ["name": "Osman"])

// Nil-coalescing fallback
translator("home.title") ?? "My App"

Variable interpolation uses {{variableName}} syntax in your translation strings:

JSON
{
  "home.greeting": "Hello, {{name}}!"
}