// // AppLocalization.swift // App for Indeed // // English-first localization using Localizable.strings (same pattern as the LinkedIn app). // Add more locales by creating `.lproj/Localizable.strings` and extending AppLanguage. // import Foundation enum AppLanguage: CaseIterable { case english case arabic case chineseSimplified var localeIdentifier: String { switch self { case .english: return "en" case .arabic: return "ar" case .chineseSimplified: return "zh-Hans" } } static var systemLanguage: AppLanguage { let preferred = Locale.preferredLanguages.first ?? "en" if preferred.lowercased().hasPrefix("zh") { return .chineseSimplified } for language in AppLanguage.allCases where preferred.hasPrefix(language.localeIdentifier) { return language } return .english } /// Settings language picker labels — fixed English names, not localized. var localizedDisplayName: String { switch self { case .english: return "English" case .arabic: return "Arabic" case .chineseSimplified: return "Chinese (Simplified)" } } } func appLocalized(_ key: String, language: AppLanguage) -> String { guard let path = Bundle.main.path(forResource: language.localeIdentifier, ofType: "lproj"), let bundle = Bundle(path: path) else { return key } return bundle.localizedString(forKey: key, value: key, table: nil) } func currentAppLanguage() -> AppLanguage { let code = UserDefaults.standard.string(forKey: "com.appforindeed.preferredLanguage") ?? "en" return AppLanguage.allCases.first(where: { $0.localeIdentifier == code }) ?? .english } /// Resolves copy for the user’s currently selected language. func L(_ key: String) -> String { appLocalized(key, language: currentAppLanguage()) } /// Localized CV template title; `name` is always the English localization key. func localizedTemplateName(_ nameKey: String) -> String { L(nameKey) } @MainActor final class AppLanguageManager { static let shared = AppLanguageManager() static let didChangeNotification = Notification.Name("AppLanguageManager.didChange") private enum UserDefaultsKey { static let preferredLanguage = "com.appforindeed.preferredLanguage" } var current: AppLanguage { currentAppLanguage() } func applyStoredPreferenceOnLaunch() { // UI copy uses `appLocalized`; do not drive layout from `AppleLanguages` (Arabic forces RTL and breaks CV templates). UserDefaults.standard.removeObject(forKey: "AppleLanguages") if UserDefaults.standard.string(forKey: UserDefaultsKey.preferredLanguage) == nil { setLanguage(AppLanguage.systemLanguage, notify: false) } } func setLanguage(_ language: AppLanguage, notify: Bool = true) { let code = language.localeIdentifier UserDefaults.standard.set(code, forKey: UserDefaultsKey.preferredLanguage) UserDefaults.standard.removeObject(forKey: "AppleLanguages") if notify { NotificationCenter.default.post(name: Self.didChangeNotification, object: self) } } func setLanguage(code: String, notify: Bool = true) { guard let language = AppLanguage.allCases.first(where: { $0.localeIdentifier == code }) else { return } setLanguage(language, notify: notify) } }