-
Notifications
You must be signed in to change notification settings - Fork 47
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Simplify TranslationsLoader and add LoadedTranslation struct with cor…
…responding type
- Loading branch information
Showing
3 changed files
with
111 additions
and
79 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
// | ||
// LoadedTranslation.swift | ||
// Swifternalization | ||
// | ||
// Created by Tomasz Szulc on 30/07/15. | ||
// Copyright (c) 2015 Tomasz Szulc. All rights reserved. | ||
// | ||
|
||
import Foundation | ||
|
||
/** | ||
Specifies few types of available translation type. | ||
*/ | ||
enum LoadedTranslationType { | ||
/** | ||
Simple key-value pair. | ||
|
||
"welcome": "welcome" | ||
*/ | ||
case Simple | ||
|
||
/** | ||
Pair where value is a dictionary with expressions. | ||
|
||
"cars": { | ||
"one": "1 car", | ||
"ie:x=2": "2 cars", | ||
"more": "%d cars" | ||
} | ||
*/ | ||
case WithExpressions | ||
|
||
/** | ||
Pair where value is a dictionary with length variations. | ||
|
||
"forgot-password": { | ||
"@100": "Forgot Password? Help.", | ||
"@200": "Forgot Password? Get password Help.", | ||
"@300": "Forgotten Your Password? Get password Help." | ||
} | ||
*/ | ||
case WithLengthVariations | ||
|
||
/** | ||
Pair where value is dictionary that contains dictionary with expression and | ||
length variations. | ||
|
||
"car-sentence": { | ||
"one": { | ||
"@100": "one car", | ||
"@200": "just one car", | ||
"@300": "you've got just one car" | ||
}, | ||
|
||
"more": { | ||
"@100": "%d cars", | ||
"@300": "you've got %d cars" | ||
} | ||
} | ||
*/ | ||
case WithExpressionsAndLengthVariations | ||
|
||
/// Not supported type. | ||
case NotSupported | ||
} | ||
|
||
/** | ||
Struct that represents loaded translation. | ||
*/ | ||
struct LoadedTranslation { | ||
/// A type of translation. | ||
let type: LoadedTranslationType | ||
|
||
/// A content of translation just loaded from a file. | ||
let content: Dictionary<String, AnyObject> | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,103 +1,53 @@ | ||
import Foundation | ||
|
||
/** | ||
Represents translations loader. | ||
Class is looking for json file named as country code. | ||
It parse such file. | ||
/** | ||
Class that loads translations from a file. | ||
*/ | ||
final class TranslationsLoader: JSONFileLoader { | ||
|
||
typealias DictWithStrings = Dictionary<String, String> | ||
typealias DictWithDicts = Dictionary<String, DictWithStrings> | ||
|
||
enum ElementType { | ||
case NotSupported | ||
case TranslationWithLengthVariations | ||
case TranslationWithLoadedExpressions | ||
case TranslationWithLengthVariationsAndLoadedExpressions | ||
} | ||
|
||
/** | ||
Method loads a file and parses it. | ||
Loads content from file with name equal to passed country code in a bundle. | ||
|
||
:params: countryCode A country code. | ||
|
||
:return: translations parsed from the file. | ||
:params: bundle A bundle when file is placed. | ||
:return: `LoadedTranslation` objects from specified file. | ||
*/ | ||
class func loadTranslations(countryCode: CountryCode, bundle: NSBundle = NSBundle.mainBundle()) -> [TranslationType] { | ||
var loadedTranslations = [TranslationType]() | ||
let json = self.load(countryCode, bundle: bundle) | ||
if json == nil { return [TranslationType]() } | ||
|
||
for (translationKey, value) in json! { | ||
if let translationValue = value as? String { | ||
loadedTranslations.append(TranslationSimple(key: translationKey, value: translationValue)) | ||
} else { | ||
let dictionary = value as! JSONDictionary | ||
switch detectElementType(dictionary) { | ||
case .TranslationWithLengthVariations: | ||
let variations = parseLengthVariations(dictionary as! DictWithStrings) | ||
loadedTranslations.append(TranslationLengthVariation(key: translationKey, variations: variations)) | ||
|
||
case .TranslationWithLoadedExpressions: | ||
let expressions = parseExpressions(dictionary as! DictWithStrings) | ||
loadedTranslations.append(ProcessableTranslationExpression(key: translationKey, loadedExpressions: expressions)) | ||
|
||
case .TranslationWithLengthVariationsAndLoadedExpressions: | ||
var expressions = [ProcessableLengthVariationExpression]() | ||
for (expressionIdentifier, lengthVariationsDict) in dictionary as! DictWithDicts { | ||
let variations = parseLengthVariations(lengthVariationsDict) | ||
expressions.append(ProcessableLengthVariationExpression(identifier: expressionIdentifier, variations: variations)) | ||
class func loadTranslations(countryCode: CountryCode, bundle: NSBundle = NSBundle.mainBundle()) -> [LoadedTranslation] { | ||
var loadedTranslations = [LoadedTranslation]() | ||
if let json = self.load(countryCode, bundle: bundle) { | ||
for (key, value) in json { | ||
if value is String { | ||
loadedTranslations.append(LoadedTranslation(type: .Simple, content: [key: value])) | ||
} else { | ||
let dictionary = value as! JSONDictionary | ||
let type = detectElementType(dictionary) | ||
if type != .NotSupported { | ||
loadedTranslations.append(LoadedTranslation(type: type, content: dictionary)) | ||
} | ||
loadedTranslations.append(ProcessableTranslationExpressionLengthVariationExpression(key: translationKey, expressions: expressions)) | ||
|
||
case .NotSupported: | ||
// Do nothing | ||
continue | ||
} | ||
} | ||
} | ||
|
||
return loadedTranslations | ||
} | ||
|
||
private class func parseLengthVariations(dict: DictWithStrings) -> [LengthVariation] { | ||
var variations = [LengthVariation]() | ||
for (key, translationValue) in dict { | ||
let numberValue = parseNumberFromLengthVariation(key) | ||
variations.append(LengthVariation(length: numberValue, value: translationValue)) | ||
} | ||
return variations | ||
} | ||
|
||
private class func parseExpressions(dict: DictWithStrings) -> [ProcessableExpressionSimple] { | ||
var expressions = [ProcessableExpressionSimple]() | ||
for (expressionKey, translationValue) in dict { | ||
expressions.append(ProcessableExpressionSimple(identifier: expressionKey, value: translationValue)) | ||
} | ||
return expressions | ||
} | ||
/** | ||
Analyzes passed dictionary and checks its content to match it to some translation type. | ||
|
||
private class func detectElementType(element: JSONDictionary) -> ElementType { | ||
|
||
if element is DictWithStrings { | ||
if let key = element.keys.first { | ||
let toIndex = advance(key.startIndex, 1) | ||
let firstCharacter = key.substringToIndex(toIndex) | ||
if firstCharacter == "@" { | ||
return .TranslationWithLengthVariations | ||
} else { | ||
return .TranslationWithLoadedExpressions | ||
} | ||
} | ||
:params: element A dictionary that will be analyzed. | ||
:returns: translation type of a dictionary. | ||
*/ | ||
private class func detectElementType(element: JSONDictionary) -> LoadedTranslationType { | ||
typealias DictWithStrings = Dictionary<String, String> | ||
typealias DictWithDicts = Dictionary<String, DictWithStrings> | ||
|
||
if element is DictWithStrings, let key = element.keys.first { | ||
let toIndex = advance(key.startIndex, 1) | ||
return key.substringToIndex(toIndex) == "@" ? .WithLengthVariations : .WithExpressions | ||
} else if element is DictWithDicts { | ||
return .TranslationWithLengthVariationsAndLoadedExpressions | ||
return .WithExpressionsAndLengthVariations | ||
} | ||
|
||
return .NotSupported | ||
} | ||
|
||
private class func parseNumberFromLengthVariation(string: String) -> Int { | ||
return (Regex.matchInString(string, pattern: "@(\\d+)", capturingGroupIdx: 1)! as NSString).integerValue | ||
} | ||
} |