Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 24 additions & 24 deletions LocalizationManager.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -91,15 +91,15 @@
B464DB702319CCAE00713265 /* LocalizationManager+ApplicationState.swift in Sources */ = {isa = PBXBuildFile; fileRef = B464DB6C2319CCAE00713265 /* LocalizationManager+ApplicationState.swift */; };
B4B6C94F231ECB8B001A8E5C /* DefaultLanguage.swift in Sources */ = {isa = PBXBuildFile; fileRef = B4B6C94E231ECB8B001A8E5C /* DefaultLanguage.swift */; };
B4B6C954231ED7B8001A8E5C /* LocalizationManager_iOS.h in Headers */ = {isa = PBXBuildFile; fileRef = B4B6C953231ED7B7001A8E5C /* LocalizationManager_iOS.h */; settings = {ATTRIBUTES = (Public, ); }; };
B4B6C966231ED7D4001A8E5C /* Localization_da-DK.json in Resources */ = {isa = PBXBuildFile; fileRef = B4B6C956231ED7D4001A8E5C /* Localization_da-DK.json */; };
B4B6C967231ED7D4001A8E5C /* Localization_da-DK.json in Resources */ = {isa = PBXBuildFile; fileRef = B4B6C956231ED7D4001A8E5C /* Localization_da-DK.json */; };
B4B6C968231ED7D4001A8E5C /* Localization_da-DK.json in Resources */ = {isa = PBXBuildFile; fileRef = B4B6C956231ED7D4001A8E5C /* Localization_da-DK.json */; };
B4B6C969231ED7D4001A8E5C /* Localization_fr-FR.json in Resources */ = {isa = PBXBuildFile; fileRef = B4B6C957231ED7D4001A8E5C /* Localization_fr-FR.json */; };
B4B6C96A231ED7D4001A8E5C /* Localization_fr-FR.json in Resources */ = {isa = PBXBuildFile; fileRef = B4B6C957231ED7D4001A8E5C /* Localization_fr-FR.json */; };
B4B6C96B231ED7D4001A8E5C /* Localization_fr-FR.json in Resources */ = {isa = PBXBuildFile; fileRef = B4B6C957231ED7D4001A8E5C /* Localization_fr-FR.json */; };
B4B6C96C231ED7D4001A8E5C /* Localization_en-GB.json in Resources */ = {isa = PBXBuildFile; fileRef = B4B6C958231ED7D4001A8E5C /* Localization_en-GB.json */; };
B4B6C96D231ED7D4001A8E5C /* Localization_en-GB.json in Resources */ = {isa = PBXBuildFile; fileRef = B4B6C958231ED7D4001A8E5C /* Localization_en-GB.json */; };
B4B6C96E231ED7D4001A8E5C /* Localization_en-GB.json in Resources */ = {isa = PBXBuildFile; fileRef = B4B6C958231ED7D4001A8E5C /* Localization_en-GB.json */; };
B4B6C966231ED7D4001A8E5C /* Localizations_da-DK.json in Resources */ = {isa = PBXBuildFile; fileRef = B4B6C956231ED7D4001A8E5C /* Localizations_da-DK.json */; };
B4B6C967231ED7D4001A8E5C /* Localizations_da-DK.json in Resources */ = {isa = PBXBuildFile; fileRef = B4B6C956231ED7D4001A8E5C /* Localizations_da-DK.json */; };
B4B6C968231ED7D4001A8E5C /* Localizations_da-DK.json in Resources */ = {isa = PBXBuildFile; fileRef = B4B6C956231ED7D4001A8E5C /* Localizations_da-DK.json */; };
B4B6C969231ED7D4001A8E5C /* Localizations_fr-FR.json in Resources */ = {isa = PBXBuildFile; fileRef = B4B6C957231ED7D4001A8E5C /* Localizations_fr-FR.json */; };
B4B6C96A231ED7D4001A8E5C /* Localizations_fr-FR.json in Resources */ = {isa = PBXBuildFile; fileRef = B4B6C957231ED7D4001A8E5C /* Localizations_fr-FR.json */; };
B4B6C96B231ED7D4001A8E5C /* Localizations_fr-FR.json in Resources */ = {isa = PBXBuildFile; fileRef = B4B6C957231ED7D4001A8E5C /* Localizations_fr-FR.json */; };
B4B6C96C231ED7D4001A8E5C /* Localizations_en-GB.json in Resources */ = {isa = PBXBuildFile; fileRef = B4B6C958231ED7D4001A8E5C /* Localizations_en-GB.json */; };
B4B6C96D231ED7D4001A8E5C /* Localizations_en-GB.json in Resources */ = {isa = PBXBuildFile; fileRef = B4B6C958231ED7D4001A8E5C /* Localizations_en-GB.json */; };
B4B6C96E231ED7D4001A8E5C /* Localizations_en-GB.json in Resources */ = {isa = PBXBuildFile; fileRef = B4B6C958231ED7D4001A8E5C /* Localizations_en-GB.json */; };
B4B6C96F231ED7D4001A8E5C /* Localization.swift in Sources */ = {isa = PBXBuildFile; fileRef = B4B6C95A231ED7D4001A8E5C /* Localization.swift */; };
B4B6C970231ED7D4001A8E5C /* Localization.swift in Sources */ = {isa = PBXBuildFile; fileRef = B4B6C95A231ED7D4001A8E5C /* Localization.swift */; };
B4B6C971231ED7D4001A8E5C /* Localization.swift in Sources */ = {isa = PBXBuildFile; fileRef = B4B6C95A231ED7D4001A8E5C /* Localization.swift */; };
Expand Down Expand Up @@ -193,9 +193,9 @@
B490AD7123356F4B00260A17 /* AutoMockable.generated.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AutoMockable.generated.swift; sourceTree = "<group>"; };
B4B6C94E231ECB8B001A8E5C /* DefaultLanguage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DefaultLanguage.swift; sourceTree = "<group>"; };
B4B6C953231ED7B7001A8E5C /* LocalizationManager_iOS.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LocalizationManager_iOS.h; sourceTree = "<group>"; };
B4B6C956231ED7D4001A8E5C /* Localization_da-DK.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = "Localization_da-DK.json"; sourceTree = "<group>"; };
B4B6C957231ED7D4001A8E5C /* Localization_fr-FR.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = "Localization_fr-FR.json"; sourceTree = "<group>"; };
B4B6C958231ED7D4001A8E5C /* Localization_en-GB.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = "Localization_en-GB.json"; sourceTree = "<group>"; };
B4B6C956231ED7D4001A8E5C /* Localizations_da-DK.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = "Localizations_da-DK.json"; sourceTree = "<group>"; };
B4B6C957231ED7D4001A8E5C /* Localizations_fr-FR.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = "Localizations_fr-FR.json"; sourceTree = "<group>"; };
B4B6C958231ED7D4001A8E5C /* Localizations_en-GB.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = "Localizations_en-GB.json"; sourceTree = "<group>"; };
B4B6C95A231ED7D4001A8E5C /* Localization.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Localization.swift; sourceTree = "<group>"; };
B4B6C95D231ED7D4001A8E5C /* LocalizationsRepositoryMock.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LocalizationsRepositoryMock.swift; sourceTree = "<group>"; };
B4B6C95E231ED7D4001A8E5C /* FileManagerMock.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FileManagerMock.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -350,9 +350,9 @@
B4B6C955231ED7D4001A8E5C /* Resources */ = {
isa = PBXGroup;
children = (
B4B6C956231ED7D4001A8E5C /* Localization_da-DK.json */,
B4B6C957231ED7D4001A8E5C /* Localization_fr-FR.json */,
B4B6C958231ED7D4001A8E5C /* Localization_en-GB.json */,
B4B6C956231ED7D4001A8E5C /* Localizations_da-DK.json */,
B4B6C957231ED7D4001A8E5C /* Localizations_fr-FR.json */,
B4B6C958231ED7D4001A8E5C /* Localizations_en-GB.json */,
);
path = Resources;
sourceTree = "<group>";
Expand Down Expand Up @@ -752,9 +752,9 @@
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
B4B6C96D231ED7D4001A8E5C /* Localization_en-GB.json in Resources */,
B4B6C96A231ED7D4001A8E5C /* Localization_fr-FR.json in Resources */,
B4B6C967231ED7D4001A8E5C /* Localization_da-DK.json in Resources */,
B4B6C96D231ED7D4001A8E5C /* Localizations_en-GB.json in Resources */,
B4B6C96A231ED7D4001A8E5C /* Localizations_fr-FR.json in Resources */,
B4B6C967231ED7D4001A8E5C /* Localizations_da-DK.json in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand All @@ -776,9 +776,9 @@
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
B4B6C96E231ED7D4001A8E5C /* Localization_en-GB.json in Resources */,
B4B6C96B231ED7D4001A8E5C /* Localization_fr-FR.json in Resources */,
B4B6C968231ED7D4001A8E5C /* Localization_da-DK.json in Resources */,
B4B6C96E231ED7D4001A8E5C /* Localizations_en-GB.json in Resources */,
B4B6C96B231ED7D4001A8E5C /* Localizations_fr-FR.json in Resources */,
B4B6C968231ED7D4001A8E5C /* Localizations_da-DK.json in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand All @@ -793,9 +793,9 @@
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
B4B6C96C231ED7D4001A8E5C /* Localization_en-GB.json in Resources */,
B4B6C969231ED7D4001A8E5C /* Localization_fr-FR.json in Resources */,
B4B6C966231ED7D4001A8E5C /* Localization_da-DK.json in Resources */,
B4B6C96C231ED7D4001A8E5C /* Localizations_en-GB.json in Resources */,
B4B6C969231ED7D4001A8E5C /* Localizations_fr-FR.json in Resources */,
B4B6C966231ED7D4001A8E5C /* Localizations_da-DK.json in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import Foundation

/// A delegate protocol for application state observer which you should implement if you
/// want to listen to application state changes.
internal protocol ApplicationStateObserverDelegate: class {
internal protocol ApplicationStateObserverDelegate: AnyObject {

/// A function called whenever an application state changes.
///
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
import Foundation

/// A type of class that can observe application state.
internal protocol ApplicationStateObserverType: class {
internal protocol ApplicationStateObserverType: AnyObject {
var delegate: ApplicationStateObserverDelegate? { get set }
func startObserving()
func stopObserving()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

import Foundation

public protocol AcceptLanguageProviderType: class {
public protocol AcceptLanguageProviderType: AnyObject {

/// Creates the accept language provider.
///
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,12 @@ extension LocalizationManager: ApplicationStateObserverDelegate {
case .automatic:
// Update localizations when we go to foreground and update mode is automatic
updateLocalizations()

case .manual:
// Don't do anything on manual update mode
break
case .never:
// Same goes for never
break
}

case .background:
Expand Down
31 changes: 19 additions & 12 deletions LocalizationManager/Classes/Manager/LocalizationManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -215,18 +215,20 @@ public class LocalizationManager<Language, Descriptor: LocalizationDescriptor> w
stateObserver.startObserving()

// Load persisted or fallback translations
if (try? localization()) == nil {
if (try? localization(lookupPersistedLocalizations: updateMode != .never)) == nil {
parseFallbackJSONLocalizations()
}

switch updateMode {
case .automatic:
// Try updating the localizations
updateLocalizations()

case .manual:
// Don't do anything on manual update mode
break
case .never:
// Same goes for never
break
}
}

Expand Down Expand Up @@ -563,7 +565,7 @@ public class LocalizationManager<Language, Descriptor: LocalizationDescriptor> w
/// If a persisted version cannot be found, the fallback json file in the bundle will be used.
///
/// - Returns: A localizations object.
public func localization<T: LocalizableModel>(localeId: String? = nil) throws -> T {
public func localization<T: LocalizableModel>(localeId: String? = nil, lookupPersistedLocalizations: Bool = true) throws -> T {
guard let locale = localeId ?? bestFitLanguage?.locale.identifier
?? languageOverride?.locale.identifier
?? getAvailablePreferredLanguageLocale()
Expand All @@ -584,7 +586,7 @@ public class LocalizationManager<Language, Descriptor: LocalizationDescriptor> w
}

// Load persisted or fallback localizations
try createLocalizationObject(locale)
try createLocalizationObject(locale, lookupPersistedLocalizations: lookupPersistedLocalizations)

// Now we must have correct localizations, so return it
if let to = localizableObjectDictonary[locale] as? T {
Expand Down Expand Up @@ -620,22 +622,27 @@ public class LocalizationManager<Language, Descriptor: LocalizationDescriptor> w
}

/// Loads and initializes the localizations object from either persisted or fallback dictionary.
func createLocalizationObject(_ localeId: String) throws {
func createLocalizationObject(_ localeId: String, lookupPersistedLocalizations: Bool = true) throws {
let localization: LocalizationResponse<Language>
var shouldUnwrapLocalization = false

//try to use persisted localizations for locale
if let persisted = try persistedLocalization(localeId: localeId),
let typeString = userDefaults.string(forKey: Constants.Keys.persistedLocalizationType),
let localizationType = PersistedLocalizationType(rawValue: typeString) {
localization = persisted
shouldUnwrapLocalization = localizationType == .all // only unwrap when all localizations are stored
if lookupPersistedLocalizations {
//try to use persisted localizations for locale
if let persisted = try persistedLocalization(localeId: localeId),
let typeString = userDefaults.string(forKey: Constants.Keys.persistedLocalizationType),
let localizationType = PersistedLocalizationType(rawValue: typeString) {
localization = persisted
shouldUnwrapLocalization = localizationType == .all // only unwrap when all localizations are stored

} else {
//otherwise search for fallback
localization = try fallbackLocalization(localeId: localeId)
}
} else {
//otherwise search for fallback
localization = try fallbackLocalization(localeId: localeId)
}


// Figure out and set localizations
guard let parsed = try processAllLocalizations(localization, shouldUnwrap: shouldUnwrapLocalization) else {
localizableObjectDictonary.removeValue(forKey: localeId)
Expand Down
1 change: 1 addition & 0 deletions LocalizationManager/Classes/Models/UpdateMode.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,5 @@ import Foundation
public enum UpdateMode {
case automatic
case manual
case never
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,6 @@

import Foundation

public protocol LocalizationManagerDelegate: class {
public protocol LocalizationManagerDelegate: AnyObject {
func localizationManager(languageUpdated: LanguageModel?)
}
12 changes: 8 additions & 4 deletions LocalizationManagerTests/Tests/LocalizationManagerTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -159,16 +159,20 @@ class LocalizationManagerTests: XCTestCase {
func testUpdateLocalizationsFail() {
let expect = expectation(description: "")
let config = mockLocalizationConfigWithUpdate
let expectedNumberOfNilValues = 2
var currentNumberOfNilValuesReceived = 0
let localizations: [DefaultLocalizationDescriptor] = [config, mockLocalizationConfigWithUpdate, mockLocalizationConfigWithoutUpdate]
expect.expectedFulfillmentCount = 3
repositoryMock.availableLocalizations = localizations
repositoryMock.localizationsResponse = nil
manager.updateLocalizations { (error) in
XCTAssertNotNil(error)
if error != nil {
currentNumberOfNilValuesReceived += 1
}
XCTAssertTrue(currentNumberOfNilValuesReceived <= expectedNumberOfNilValues)
expect.fulfill()
}
waitForExpectations(timeout: 1.0) { (_) in
XCTFail()
}
wait(for: [expect], timeout: 1.0)
}

func testUpdateCurrentLanguageWithBestFit() {
Expand Down
2 changes: 1 addition & 1 deletion Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,4 @@ SPEC CHECKSUMS:

PODFILE CHECKSUM: 54f5f694e106ddcbcd3724c53daeefebfe959bc1

COCOAPODS: 1.8.4
COCOAPODS: 1.11.2