Skip to content

iOS localization SDK for native app text updates.

ReRune iOS SDK 1.7.0 delivers the selected variant through native Bundle.main lookup paths, with per-key Main and bundled-resource fallback.
ReRune projects list showing real localization projects in a workspace
ReRune dashboard showing localization workspace activity and project statusReRune dashboard showing localization workspace activity and project statusReRune dashboard showing localization workspace activity and project status
ReRune OTA demo mobile app landing screen with live localization status

Common challenge

Bundled .strings and .xcstrings remain the safe baseline, but app teams need a controlled path for approved text changes after release.

Best fit

iOS teams that want ReRune 1.7.0 through Swift Package Manager, runtime variants, native localization behavior, and OTA update delivery.

How ReRune helps

ReRune keeps iOS OTA delivery tied to project context, glossaries, language progress, and the same translation workspace used by other product surfaces.

iOS specifics

Native Foundation lookup remains the center of the iOS integration.

ReRune installs through Swift Package Manager and applies published values through targeted Bundle.main localization behavior, while bundled .strings, .stringsdict, and .xcstrings content remains available.
  1. Use native lookup calls

    UIKit and SwiftUI code should resolve OTA-aware text through NSLocalizedString(...) or Bundle.main.localizedString(...). The current phase targets the default Localizable table in Bundle.main. SwiftUI Text("key") also shows ReRune values.

  2. Rebind UIKit or observe SwiftUI revisions

    In UIKit, subscribe to reRuneRevisionPublisher and set visible text again. On iOS 17 and later, SwiftUI views that read NSLocalizedString(...) in body update by themselves. Before iOS 17, add .reRuneObserveRevision() near the top of the screen.

  3. Expose cached dashboard languages

    reRuneAvailableLocaleDetails combines compiled and successfully applied dashboard locales. Apps can call reRuneSetLocale(...) for an in-app picker and persist that choice themselves, passing it to reRuneSetLocale(...) right before reRuneSetup(...) on the next launch.

  4. Respect the current SwiftUI and platform boundary

    String(localized:), LocalizedStringResource, and AttributedString(localized:) are not served, and a SwiftUI Text already on screen keeps its text until SwiftUI creates it again. New keys, native system text, Settings language lists, and App Store metadata still require an app release.

SDK technical reference

ReRune for iOS

Ship OTA localization updates and runtime variants in native iOS apps while keeping UIKit and SwiftUI on Apple's localization APIs.

Version-pinned guidance from the published package README. Follow the linked README for the complete API and current release notes.

Package
ReRune
Current release
1.7.0
Requirements
iOS 15+, Swift tools 5.9+, Swift Package Manager

Install command

.package(url: "https://github.com/BasalBit/rerune-ios.git", from: "1.7.0")

README at a glance

Runtime contract

  • Install with Swift Package Manager and import ReRune in UIKit or SwiftUI
  • Keep using Text("key"), NSLocalizedString(...), or Bundle.main.localizedString(...) for OTA-aware text
  • Works with bundled .strings, .stringsdict, and .xcstrings localization assets
  • Updates SwiftUI by itself on iOS 17+. Use reRuneRevisionPublisher for UIKit or .reRuneObserveRevision() before iOS 17
  • Select Main or a named translation variant at setup or runtime
  • Preview enabled drafts in an isolated staging mode before publishing
iOSSwift.xcstringsUIKitSwiftUI

Quick Start

UI stack

SwiftUI quick start

// Swift Package Manager
// https://swiftpackageindex.com/BasalBit/rerune-ios
// Version: 1.7.0

import ReRune

import SwiftUI

@main
struct ExampleApp: App {
  init() {
    reRuneSetup(
      otaPublishId: "replace-with-ota-publish-id",
      variant: ReRuneVariant("customer_acme")
    )
  }

  var body: some Scene {
    WindowGroup {
      ContentView()
    }
  }
}

struct ContentView: View {
  var body: some View {
    VStack {
      Text(NSLocalizedString("title", comment: ""))
      Text(Bundle.main.localizedString(forKey: "subtitle", value: nil, table: nil))
    }
    // Needed only below iOS 17; deprecated on iOS 17 and later.
    .reRuneObserveRevision()
  }
}

Native lookup path

Text("key") shows ReRune values when SwiftUI creates the view. For text that must update on screen, read it with NSLocalizedString(...) in the view body. On iOS 17 and later those views update by themselves. Before iOS 17, add .reRuneObserveRevision() near the top of the screen.

Current SwiftUI scope

SwiftUI Text("key") and views that take a key show ReRune values. String(localized:), LocalizedStringResource, and AttributedString(localized:) do not, so use NSLocalizedString(...) for those strings.

Workflow

From app copy to release-ready localization.

ReRune connects translation management to the delivery path developers already use: dashboard work, AI assistance, CLI/API sync, and OTA updates where a supported SDK is installed.

Install the SDK

Connect the supported app runtime to a ReRune publish ID while keeping native or framework localization behavior in place.

Publish approved text

Approve translation changes in the workspace, then publish runtime updates without turning every text fix into a full store release.

Refresh visible copy

Let supported SDK hooks check for updates and refresh text when new approved localization payloads are available.

Keep fallbacks intact

When runtime updates are unavailable, the app keeps reading bundled resources so localization failures do not break the product.

Setup WizardAI Coding Agent

One command. A wizard sets the stage, your AI agent ships it.

Run the onboarding command from the root of your Git repository. The wizard inspects the app and confirms the plan with you, with no AI involved and nothing changed yet. Then it opens the coding agent you already use with a complete migration workflow.

Run inside your Git repository

curl -fsSL https://rerune.io/onboard.sh | sh

The script runs locally. ReRune does not receive your source code or list of installed agents.

Coding agent integrations

11 integrations: 4 available now, 7 planned.

  • Claude CodeReady
  • CodexReady
  • OpenCodeReady
  • PiReady
  • GitHub Copilot CLIPlanned
  • GoosePlanned
  • Qwen CodePlanned
  • Cursor AgentPlanned
  • Kiro CLIPlanned
  • Cline CLIPlanned
  • Factory DroidPlanned

Coverage

App-first does not mean mobile-only.

Start where localization creates release friction, then keep web, mobile, and cross-platform products in one shared workspace as your surface area grows.

Developer delivery

Sync through the CLI. Publish through OTA SDKs.

Use the ReRune CLI locally or in CI/CD to manage project translations, then deliver approved runtime updates through the SDK built for your app.

Companion CLI

Install the ReRune CLI

Use the ReRune CLI to sync, validate, and manage translations right from your terminal. Run syncs in CI/CD or locally whenever you need to push a new language.

Homebrew (macOS/Linux):

brew install BasalBit/tap/rerune
  • Downloadable builds for macOS, Linux, and Windows
  • Uses the API keys you generate in the dashboard
  • Fits scripted CI/CD workflows through CLI and API access
rerune

Connect the project

Create the project config and connect the repository to its ReRune workspace.

rerune pull

Pull approved updates

Bring current dashboard translations into the app or its build workflow.

rerune push

Push local changes

Send local translation updates back to ReRune for the team to manage and publish.

Questions

Questions teams ask before choosing a localization platform.

Contact the ReRune team

Share an idea, report a problem, or ask for help with ReRune.

Can an iOS app keep using .xcstrings with ReRune?

Yes. ReRune 1.7.0 applies the selected variant through native Bundle.main lookups while bundled .xcstrings remain available as fallback. It does not deliver .xcstrings files as the OTA transport.

Does ReRune replace UIKit or SwiftUI localization APIs?

No. ReRune is designed to work alongside native localization behavior, with bundled resources remaining the fallback when runtime updates are unavailable.

How should SwiftUI read ReRune OTA strings?

Text("key") and views that take a key show ReRune values when SwiftUI creates them. For text that must update on a visible screen, use NSLocalizedString(...) in the SwiftUI view body. Views update by themselves on iOS 17 and later. Before iOS 17, add .reRuneObserveRevision() near the top of the screen. String(localized:) and LocalizedStringResource do not receive ReRune translations.

Can ReRune add an iOS language that is not compiled in the app bundle?

Yes. After a successful fetch, dashboard-only languages can appear through reRuneAvailableLocaleDetails and can be selected with reRuneSetLocale(...). iOS Settings and App Store language metadata are unchanged.

Which iOS localization resources remain the fallback?

Bundled .strings, .stringsdict, and .xcstrings values remain available through Foundation lookup. The current OTA scope targets Bundle.main and the default Localizable table.

Explore next

Go deeper into the developer, platform, and delivery workflows connected to this page.

OTA localization updates without making every copy fix a release.

Deliver published app text through ReRune OTA SDKs, preview enabled drafts in staging clients, and keep production caches isolated with fallback and rollback.

Android localization SDK for native app text updates.

Use ReRune Android Compose or Views SDK 1.8.0 for OTA strings and runtime variants with per-key Main and native resource fallback.

Flutter localization with OTA updates on top of your existing flow.

Use ReRune Flutter SDK 1.9.1 for OTA localization and runtime variants while keeping generated delegates, bundled resources, CLI sync, and AI assistance.

One workspace

Start with one product workflow and expand from there.

Create projects, manage keys, use AI assistance with context, sync through CLI/API, and publish approved runtime updates when your app uses a supported ReRune SDK.