1 // Copyright 2021-present 650 Industries. All rights reserved.
2 
3 import Foundation
4 import ExpoModulesCore
5 
6 public class LocalizationModule: Module {
7   public func definition() -> ModuleDefinition {
8     Name("ExpoLocalization")
9 
10     Constants {
11       return Self.getCurrentLocalization()
12     }
13 
14     AsyncFunction("getLocalizationAsync") {
15       return Self.getCurrentLocalization()
16     }
17   }
18 
19   // If the application isn't manually localized for the device language then the
20   // native `Locale.current` will fallback on using English US
21   // [cite](https://stackoverflow.com/questions/48136456/locale-current-reporting-wrong-language-on-device).
22   // This method will attempt to return the locale that the device is using regardless of the app,
23   // providing better parity across platforms.
24   static func getPreferredLocale() -> Locale {
25       guard let preferredIdentifier = Locale.preferredLanguages.first else {
26           return Locale.current
27       }
28       return Locale(identifier: preferredIdentifier)
29   }
30 
31   static func getCurrentLocalization() -> [String: Any?] {
32     let locale = getPreferredLocale()
33     let languageCode = locale.languageCode ?? "en"
34     var languageIds = Locale.preferredLanguages
35 
36     if languageIds.isEmpty {
37       languageIds.append("en-US")
38     }
39     return [
40       "currency": locale.currencyCode ?? "USD",
41       "decimalSeparator": locale.decimalSeparator ?? ".",
42       "digitGroupingSeparator": locale.groupingSeparator ?? ",",
43       "isoCurrencyCodes": Locale.isoCurrencyCodes,
44       "isMetric": locale.usesMetricSystem,
45       "isRTL": Locale.characterDirection(forLanguage: languageCode) == .rightToLeft,
46       "locale": languageIds.first,
47       "locales": languageIds,
48       "region": locale.regionCode ?? "US",
49       "timezone": TimeZone.current.identifier
50     ]
51   }
52 }
53