Skip to content

Commit

Permalink
Paywalls: prioritize Locale.current over Locale.preferredLocales (
Browse files Browse the repository at this point in the history
#3657)

Fixes #3655.
Follow up to #3633.

This improves upon that PR by using `Locale.current.removingRegion` for
each locale **before** trying to look up `Locale.preferredLocales`.

This fixes this scenario:
- Configure your phone with: `en_IN` and `es_ES`
- Launch paywall with localization `en_US` and `es_ES`

Prior to this change, we'd be looking up localizations in this order:
- `en_IN`
- `es_ES`
- `en` (no region)

Because there _is_ a localization for `es_ES` we'd return that one
before attempting to look up `Locale.current.removingRegion`.

Example of the new log:
> VERBOSE: Looking up localized configuration for ["en_IN", "es_ES"],
searching for ["en_IN", "en", "es_ES", "es"]
> VERBOSE: Found localized configuration for 'en'
  • Loading branch information
NachoSoto authored Feb 8, 2024
1 parent 62e8f19 commit 6ef1e5d
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 18 deletions.
7 changes: 4 additions & 3 deletions Sources/Logging/Strings/PaywallsStrings.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ enum PaywallsStrings {
case caching_presented_paywall
case clearing_presented_paywall

case looking_up_localization([Locale])
case looking_up_localization(preferred: [Locale], search: [Locale])
case found_localization(Locale)
case fallback_localization(localeIdentifier: String)

Expand Down Expand Up @@ -60,8 +60,9 @@ extension PaywallsStrings: LogMessage {
case .clearing_presented_paywall:
return "PurchasesOrchestrator: clearing presented paywall"

case let .looking_up_localization(locales):
return "Looking up localized configuration for \(locales.map(\.identifier))"
case let .looking_up_localization(preferred, search):
return "Looking up localized configuration for \(preferred.map(\.identifier)), " +
"searching for \(search.map(\.identifier))"

case let .found_localization(locale):
return "Found localized configuration for '\(locale.identifier)'"
Expand Down
17 changes: 8 additions & 9 deletions Sources/Paywalls/PaywallData+Localization.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,13 @@ public extension PaywallData {
}

// Visible for testing
internal func localizedConfiguration(for locales: [Locale]) -> LocalizedConfiguration {
Logger.verbose(Strings.paywalls.looking_up_localization(locales))
internal func localizedConfiguration(for preferredLocales: [Locale]) -> LocalizedConfiguration {
// Allows us to search each locale in order of priority, both with the region and without.
// Example: [en_UK, es_ES] => [en_UK, en, es_ES, es]
let locales: [Locale] = preferredLocales.flatMap { [$0, $0.removingRegion].compactMap { $0 } }

Logger.verbose(Strings.paywalls.looking_up_localization(preferred: preferredLocales,
search: locales))

let result: (locale: Locale, config: LocalizedConfiguration)? = locales
.lazy
Expand All @@ -50,13 +55,7 @@ public extension PaywallData {
/// - Returns: The list of locales that paywalls should try to search for.
/// Includes `Locale.current` and `Locale.preferredLanguages`.
internal static var localesOrderedByPriority: [Locale] {
var result = [.current] + Locale.preferredLocales

if let withoutRegion = Locale.current.removingRegion {
result.append(withoutRegion)
}

return result
return [.current] + Locale.preferredLocales
}

private var fallbackLocalizedConfiguration: (String, LocalizedConfiguration) {
Expand Down
19 changes: 13 additions & 6 deletions Tests/UnitTests/Paywalls/PaywallDataTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -127,9 +127,18 @@ class PaywallDataTests: BaseHTTPResponseTest {

let enConfig = try XCTUnwrap(paywall.localizedConfiguration(for: [
.init(identifier: "en_IN"),
.init(identifier: "en-IN"),
.init(identifier: "en-IN").removingRegion
].compactMap { $0 }))
.init(identifier: "en-IN")
]))
expect(enConfig.title) == "Paywall"
}

func testLocalizedConfigurationLooksForCurrentLocaleWithoutRegionBeforePreferedLocales() throws {
let paywall: PaywallData = try self.decodeFixture("PaywallData-Sample1")

let enConfig = try XCTUnwrap(paywall.localizedConfiguration(for: [
.init(identifier: "en_IN"),
.init(identifier: "es_ES")
]))
expect(enConfig.title) == "Paywall"
}

Expand All @@ -139,14 +148,12 @@ class PaywallDataTests: BaseHTTPResponseTest {
if #available(iOS 17.0, tvOS 17, watchOS 10, *) {
expected = [
"en_US",
"en-US",
"en"
"en-US"
]
} else {
expected = [
"en_US",
// `Locale.preferredLanguages` returns `en` before iOS 17.
"en",
"en"
]
}
Expand Down

0 comments on commit 6ef1e5d

Please sign in to comment.