Конвертировать файл localizable.string в JSON в iOS swift - PullRequest
0 голосов
/ 09 января 2020

У меня есть 3 локализуемых файла в моем проекте Localizable.string (Engli sh), Localizable.string (немецкий) и Localizable.string (французский) с несколькими ключами и значениями формы localizationKey1 = "Text1 in english";. Я хочу, чтобы они были преобразованы в один json файл в формате

{
    "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
}

Как мне go об этом?

РЕДАКТИРОВАТЬ: Я смог в требуемый формат JSON, основанный на ответе @Francis, но порядки внешних и внутренних ключей перепутаны. Есть ли способ их заказать?

Ответы [ 2 ]

1 голос
/ 10 января 2020

Попробуйте это

        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)
        }
0 голосов
/ 09 января 2020

Вы можете попробовать прочитать файл как обычный UTF8 текстовый файл. Вы должны перебирать строки, разбивать строки на компоненты, разделенные знаком "=", и помещать результат в какой-то словарь Затем сериализуйте словарь в JSON данные.

Может быть что-то вроде следующего:

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)
}

Этот метод не проверен, а просто написан на лету. У этого также есть 3 пункта, которые все еще должны быть реализованы, чтобы удалить все лишние части и игнорировать нерелевантные линии.

Использование будет выглядеть так:

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")    
])

Я надеюсь, что это по крайней мере получит ты начал. Я предлагаю вам задать другие более конкретные c вопросы, если что-то go не так или у вас возникли проблемы с поиском ответов по частям, которые еще предстоит сделать.

...