Implementing Dynamic Language Switching in Mobile App

NOVASOLUTIONS.TECHNOLOGY is engaged in the development, support and maintenance of iOS, Android, PWA mobile applications. We have extensive experience and expertise in publishing mobile applications in popular markets like Google Play, App Store, Amazon, AppGallery and others.
Development and support of all types of mobile applications:
Information and entertainment mobile applications
News apps, games, reference guides, online catalogs, weather apps, fitness and health apps, travel apps, educational apps, social networks and messengers, quizzes, blogs and podcasts, forums, aggregators
E-commerce mobile applications
Online stores, B2B apps, marketplaces, online exchanges, cashback services, exchanges, dropshipping platforms, loyalty programs, food and goods delivery, payment systems.
Business process management mobile applications
CRM systems, ERP systems, project management, sales team tools, financial management, production management, logistics and delivery management, HR management, data monitoring systems
Electronic services mobile applications
Classified ads platforms, online schools, online cinemas, electronic service platforms, cashback platforms, video hosting, thematic portals, online booking and scheduling platforms, online trading platforms

These are just some of the types of mobile applications we work with, and each of them may have its own specific features and functionality, tailored to the specific needs and goals of the client.

Showing 1 of 1 servicesAll 1735 services
Implementing Dynamic Language Switching in Mobile App
Medium
from 1 business day to 3 business days
FAQ
Our competencies:
Development stages
Latest works
  • image_mobile-applications_feedme_467_0.webp
    Development of a mobile application for FEEDME
    756
  • image_mobile-applications_xoomer_471_0.webp
    Development of a mobile application for XOOMER
    624
  • image_mobile-applications_rhl_428_0.webp
    Development of a mobile application for RHL
    1054
  • image_mobile-applications_zippy_411_0.webp
    Development of a mobile application for ZIPPY
    947
  • image_mobile-applications_affhome_429_0.webp
    Development of a mobile application for Affhome
    862
  • image_mobile-applications_flavors_409_0.webp
    Development of a mobile application for the FLAVORS company
    445

Implementing Dynamic Language Switching in Mobile Applications

Language switching without app restart — task looks trivial until hitting that half strings changed, but Fragment with ViewPager2 remained on old language because survived config change through setRetainInstance(true). Or DateTimeFormatter cached Locale on first call and now formats dates in Russian, though user selected English three screens ago.

Why This Is More Complex Than Seems

Android

Standard way — AppCompatDelegate.setApplicationLocales(LocaleListCompat) from AndroidX (API 33+ natively, AndroidX backport works to API 21). Before AndroidX had to manually recreate Configuration and restart Activity.

Problem with setApplicationLocales: saves user choice in system app settings. Good for integration with system Language Settings, breaks scenario when locale managed from backend (multi-tenant apps where language set by profile). Then need custom ContextWrapper overriding attachBaseContext, wrapping Context with needed Locale before Activity starts inflating layout.

ViewModel doesn't recreate on locale change through setApplicationLocales — survives config change. Strings inside ViewModel (if got there — architecture error) remain on old language. Strings in LiveData<String> or StateFlow<String> either store as @StringRes Int and format in View, or re-emit after locale change.

RecyclerView.Adapter with cached strings needs explicitly pull through notifyDataSetChanged() or better through DiffUtil, otherwise already rendered items won't re-render.

iOS

Bundle.main.localizedString(forKey:value:table:) reads strings from loaded bundle — bundle of locale active at startup. UserDefaults.standard.set(["ru"], forKey: "AppleLanguages") changes language only after next launch. This iOS limitation before version 13.

For iOS 13+ correct way — Bundle swizzling: create custom Bundle overriding localizedString(forKey:) reading from needed locale bundle. Typical implementation — through Bundle extension storing current languageBundle in static variable:

private var bundleKey: UInt8 = 0

class LanguageBundle: Bundle {
    override func localizedString(forKey key: String,
                                   value: String?,
                                   table tableName: String?) -> String {
        guard let bundle = objc_getAssociatedObject(self, &bundleKey) as? Bundle else {
            return super.localizedString(forKey: key, value: value, table: tableName)
        }
        return bundle.localizedString(forKey: key, value: value, table: tableName)
    }
}

extension Bundle {
    static func setLanguage(_ language: String) {
        object_setClass(Bundle.main, LanguageBundle.self)
        let path = Bundle.main.path(forResource: language, ofType: "lproj")
        let bundle = path.flatMap { Bundle(path: $0) } ?? Bundle.main
        objc_setAssociatedObject(Bundle.main, &bundleKey, bundle, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        NotificationCenter.default.post(name: .languageDidChange, object: nil)
    }
}

SwiftUI simplifies: environment(\.locale, Locale(identifier: "ar")) on root View — all child views re-render with new locale. Strings through LocalizedStringKey picked automatically.

But UIViewController-based screens in SwiftUI-wrapper through UIViewControllerRepresentable need explicit trigger — NotificationCenter or @Published rebuild flag.

Flutter

MaterialApp(locale: _currentLocale) + setState — standard approach. Package flutter_localizations + intl for formatting. Locale change through Provider or Riverpod (Notifier with Locale-state) — UI re-builds reactively.

Case from practice: app with cached_network_image — on language change cache with alt-text images cleared (because cache key included locale-dependent URL). Solution — locale-agnostic cache keys.

What We Do

  • Choose storage mechanism: SharedPreferences/UserDefaults or server profile
  • Implement locale-provider with reactive state (Riverpod / Room + Flow / Combine)
  • Audit all date, number, currency formatting places — NumberFormat, DateFormat can't cache with locale
  • Test switching on all key screens including deep link and push-notification landing pages

Timeframe: 1-3 days depending on architecture. Cost calculated after codebase analysis.