I have 3 Localizable files in my project Localizable.string(English), Localizable.string(German) and Localizable.string(French) with several keys and values of form localizationKey1 = "Text1 in english";
. I want them to be converted in a single json file in format
{
"localizationKey1": {
"en": "Text1 in english",
"de": "Text1 in german",
"fr": "Text1 in french"
},
"localizationKey2": {
"en": "Text2 in english",
"de": "Text2 in german",
"fr": "Text2 in french"
} and so on depending on number of keys
}
How do I go about it?
EDIT: I was able to the required JSON format based on the answer by @Francis but the orders of the outer and inner keys are messed up. Is there any way to order them?
Try this
let path1 = (Bundle.main.path(forResource: "Localizable", ofType: "strings", inDirectory: nil, forLocalization: "en"))
let path2 = (Bundle.main.path(forResource: "Localizable", ofType: "strings", inDirectory: nil, forLocalization: "de"))
let path3 = (Bundle.main.path(forResource: "Localizable", ofType: "strings", inDirectory: nil, forLocalization: "fr"))
let dict1 = NSDictionary(contentsOfFile: path1!)
let dict2 = NSDictionary(contentsOfFile: path2!)
let dict3 = NSDictionary(contentsOfFile: path3!)
var newDict = [String : Any]()
for (key, value) in dict1! {
var value2 = ""
var value3 = ""
if let keyVal = dict2?[key] as? String {
value2 = keyVal
}
if let keyVal = dict3?[key] as? String {
value3 = keyVal
}
let tempDict = ["en": value, "de": value2, "fr": value3]
newDict["\(key)"] = tempDict
}
do {
let data = try JSONSerialization.data(withJSONObject: newDict, options: .prettyPrinted)
let dataString = String(data: data, encoding: .utf8)!
print(dataString) //This will give you the required JSON format
} catch {
print("JSON serialization failed: ", error)
}
You could try reading the file as normal UTF8
txt file. You would iterate through lines, break lines into components separated by " = " and put the result into some dictionary. Then serialize the dictionary into JSON data.
Maybe something like the following:
func parseLocalizationStringFilesToJSON(files: [(path: String, key: String)]) throws -> Data {
// Generate a dictionary that will be in the end parsed to JSON
var dictionary: [String: [String: String]] = [String: [String: String]]()
// Iterate through all files
try files.forEach { file in
// try reading file as UTF8 string
let fileString = try String(contentsOfFile: file.path, encoding: .utf8)
// Break down file string to lines
let lines = fileString.components(separatedBy: .newlines)
// Extract from each line
lines.forEach { line in
// TODO: Skip lines that do not start with "
let separator = " = " // A separator used to separate key-value in strings file
let lineComponents = line.components(separatedBy: separator) // Break down to components
if lineComponents.count >= 2 { // There may be more than 2 components. Imagine: localizationKey1 = "A = B";
// TODO: Trim the key to remove whitespaces and "
let key = lineComponents[0] // Key is always the first component
// TODO: Trim the value to remove whitespaces and "
let value = lineComponents[1...].joined(separator: separator) // The rest must be joined back together
var innerDictionary: [String: String] = dictionary[key] ?? [String: String]() // Extract current sub-json at this key or create a new sub-json
innerDictionary[file.key] = value // Assign a new value
dictionary[key] = innerDictionary // Put back to main dictionary
}
}
}
// Serialize it to JSON data
return try JSONSerialization.data(withJSONObject: dictionary, options: .prettyPrinted)
}
This method is not tested but just written on the fly. It also has 3 points that still need to be implemented to remove all the extra parts and to ignore irrelevant lines.
The usage would be like:
let jsonData: Data = try? parseLocalizationStringFilesToJSON(files: [
(Bundle.main.path(forResource: "Localizable", ofType: "string(English)"), "en"),
(Bundle.main.path(forResource: "Localizable", ofType: "string(German)"), "de"),
(Bundle.main.path(forResource: "Localizable", ofType: "string(French)"), "fr")
])
I hope this at least gets you started. I suggest you ask other more specific questions if things go wrong or if you have trouble finding answers on parts that are still to be done.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.