Contents

summacristian/localizerkit

**LocalizerKit** is a Swift Package that provides the foundation to localize your apps built in Swift Playground.

๐Ÿš€ Usage

First, import the package wherever you need it:

import LocalizerKit

๐Ÿ—๏ธ Creating the keyset for your strings

This package relies on an enum to define the keys used for localized strings. This improves autocomplete, avoids typos, and makes the code easier to maintain.

Your keyset should conform to LocalizedKeyProtocol, and also be RawRepresentable with String and Hashable.

enum LocalizedKey: String, LocalizedKeyProtocol {
    case welcome
    case goodbye
    // ...
}
๐Ÿง  Why use an enum for keys?

LocalizerKit ensures your keys are compiler-checked. If you reference a missing key, your code wonโ€™t compile โ€” no more runtime crashes due to typos. Plus, the IDE autocompletes your keys automatically, making localization fast, safe, and efficient.

<p align="center"> <picture> <source srcset="Assets/AutocompletePreview_Dark.jpeg" media="(prefers-color-scheme: dark)"> <source srcset="Assets/AutocompletePreview_Light.jpeg" media="(prefers-color-scheme: light)"> <img src="Assets/AutocompletePreview_Light.jpeg" width="600" alt="Autocomplete in Swift Playground"> </picture> </p>

๐Ÿ“ Defining localized strings

To define the actual strings, create one struct per supported language, conforming to LocalizedLanguage. Each struct must:

  • Specify its SupportedLanguage (e.g. .en, .it)
  • Provide a dictionary mapping keys to strings
struct EnglishStrings: LocalizedLanguage {
    static let language: SupportedLanguage = .en
    static let strings: [LocalizedKey: String] = [
        .welcome: "Welcome",
        .goodbye: "Goodbye"
    ]
}

๐Ÿ’ก Tip: While LocalizerKit supports different keysets per language, itโ€™s highly recommended to use a shared one for consistency and easier maintenance.

๐Ÿ”Œ Registering localizations

You must register each languageโ€™s struct so that Localizer knows where to look.

You can do this automatically using a SwiftUI view modifier:

WindowGroup {
    ContentView()
        .localized(in: [EnglishStrings.self, ItalianStrings.self, GermanStrings.self])
}

This modifier registers each language into LocalizerRegistry, using the language specified in each struct.

โš ๏ธ If multiple structs register for the same language, the last one will overwrite the previous entry.

๐Ÿงฉ Manual registration (advanced use)

You can skip the view modifier and register manually. For example, in your init():

init() {
    let languages = [EnglishStrings.self, ItalianStrings.self, GermanStrings.self]

    for language in languages {
        LocalizerRegistry.register(language)
    }
}

๐ŸŒ Language resolution and overrides

By default, LocalizerKit uses the first language from Locale.preferredLanguages that is also registered in LocalizerRegistry.

You can override this behavior with LocalizerSettings:

@StateObject private var settings = LocalizerSettings()

Toggle("Override system language", isOn: $settings.overrideSystemLanguages)

Picker("Language", selection: $settings.selectedLanguage) {
    ForEach(Localizer.availableLanguages, id: \.self) { lang in
        Text("\(lang.flag) \(lang.displayName)").tag(lang)
    }
}

The Localizer struct exposes two variables you can tinker with:

  • .overrideSystemLanguages: a Bool that, when set true, makes Localizer ignore the system's Locale.preferredLanguages
  • .selectedLanguage: a SupportedLanguage value that defines the app's language when override is enabled

When Localizer.overrideSystemLanguages is true, all localization lookups will use .selectedLanguage instead of the system locale. This makes it easy to detach your appโ€™s language from the deviceโ€™s settings, ideal for providing an in-app language picker for example.

๐Ÿ–ฅ๏ธ Using localized strings in views

Once set up, retrieving a localized string is simple:

Text(Localizer.get(LocalizedKey.welcome))
๐Ÿ’ก Cleaner syntax with extension

To avoid writing LocalizedKey. every time, add this helper:

extension Localizer {
    public static func get(
      _ key: LocalizedKey,
      in lang: SupportedLanguage = Localizer.currentLanguage
    ) -> String {
        return get(key as any LocalizedKeyProtocol, in: lang)
    }
}

Then use:

Text(Localizer.get(.welcome))

You can locally override the language in a specific Text:

Text(Localizer.get(.welcome, in: .fr))

๐ŸŒ Adding a new localization

To add support for a new language:

  1. Create a struct for the new language (e.g. SpanishStrings), implementing LocalizedLanguage.
  2. Add it to the .localized(in: [...]) modifier or manually register it.

Done! The app will now automatically use that language if it matches the userโ€™s preferred locale.

๐ŸŒ Supported Languages

LocalizerKit currently includes out-of-the-box translations for 30 languages, and growing. You can register just the ones you need for your app, no need to rush all of them at launch.

Supported languages include: | | | | |--------|--------|--------| | ๐Ÿ‡บ๐Ÿ‡ธ English | ๐Ÿ‡ฎ๐Ÿ‡น Italian | ๐Ÿ‡ซ๐Ÿ‡ท French | | ๐Ÿ‡ฉ๐Ÿ‡ช German | ๐Ÿ‡ช๐Ÿ‡ธ Spanish | ๐Ÿ‡ต๐Ÿ‡น Portuguese | | ๐Ÿ‡ณ๐Ÿ‡ฑ Dutch | ๐Ÿ‡ธ๐Ÿ‡ช Swedish | ๐Ÿ‡ฉ๐Ÿ‡ฐ Danish | | ๐Ÿ‡ซ๐Ÿ‡ฎ Finnish | ๐Ÿ‡ต๐Ÿ‡ฑ Polish | ๐Ÿ‡จ๐Ÿ‡ฟ Czech | | ๐Ÿ‡ท๐Ÿ‡ด Romanian | ๐Ÿ‡ญ๐Ÿ‡บ Hungarian | ๐Ÿ‡ฌ๐Ÿ‡ท Greek | | ๐Ÿ‡น๐Ÿ‡ท Turkish | ๐Ÿ‡ท๐Ÿ‡บ Russian | ๐Ÿ‡บ๐Ÿ‡ฆ Ukrainian | | ๐Ÿ‡ฎ๐Ÿ‡ฑ Hebrew | ๐Ÿ‡ธ๐Ÿ‡ฆ Arabic | ๐Ÿ‡ฎ๐Ÿ‡ณ Hindi | | ๐Ÿ‡จ๐Ÿ‡ณ Chinese | ๐Ÿ‡ฏ๐Ÿ‡ต Japanese | ๐Ÿ‡ฐ๐Ÿ‡ท Korean | | ๐Ÿ‡ป๐Ÿ‡ณ Vietnamese | ๐Ÿ‡น๐Ÿ‡ญ Thai | ๐Ÿ‡ฎ๐Ÿ‡ฉ Indonesian | | ๐Ÿ‡ฒ๐Ÿ‡พ Malay | ๐Ÿ‡ณ๐Ÿ‡ด Norwegian | ๐Ÿ‡ฎ๐Ÿ‡ท Persian |

๐Ÿ“ฆ Installation

To use LocalizerKit in your project:

  1. Open Swift Playground or Xcode.
  2. Add a Swift Package dependency with this URL:
https://github.com/SummaCristian/LocalizerKit.git
  1. Import the module in your files:
import LocalizerKit

๐Ÿ“„ License

LocalizerKit is released under the MIT License. See the LICENSE file for more details.

Package Metadata

Repository: summacristian/localizerkit

Default branch: main

README: README.md