Hi. I'm trying to create dynamic localization, but I getting an error. Please, someone, help me :)
class LocalizationManager {
var currentBundle = Bundle.main
let manager = FileManager.default
lazy var bundlePath: URL = {
let documents = URL(fileURLWithPath: NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first!)
let bundlePath = documents.appendingPathComponent(RuntimeLocalizable.bundleName, isDirectory: true)
return bundlePath
}()
public func returnCurrentBundleForLanguage(lang:String) throws -> Bundle {
if manager.fileExists(atPath: bundlePath.path) == false {
return Bundle(path: getPathForLocalLanguage(language: lang))!
}
do {
let resourceKeys : [URLResourceKey] = [.creationDateKey, .isDirectoryKey]
_ = try manager.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: false)
let enumerator = FileManager.default.enumerator(at: bundlePath ,
includingPropertiesForKeys: resourceKeys,
options: [.skipsHiddenFiles], errorHandler: { (url, error) -> Bool in
return true
})!
for case let folderURL as URL in enumerator {
_ = try folderURL.resourceValues(forKeys: Set(resourceKeys))
if folderURL.lastPathComponent == ("\(lang).lproj"){
let enumerator2 = FileManager.default.enumerator(at: folderURL,
includingPropertiesForKeys: resourceKeys,
options: [.skipsHiddenFiles], errorHandler: { (url, error) -> Bool in
return true
})!
for case let fileURL as URL in enumerator2 {
_ = try fileURL.resourceValues(forKeys: Set(resourceKeys))
if fileURL.lastPathComponent == "languages.strings" {
return Bundle(url: folderURL)!
}
}
}
}
} catch {
return Bundle(path: getPathForLocalLanguage(language: lang))!
}
return Bundle(path: getPathForLocalLanguage(language: lang))!
}
private func getPathForLocalLanguage(language: String) -> String {
return Bundle.main.path(forResource: language, ofType: "lproj")!
}
func setCurrentBundle(forLanguage:String){
do {
currentBundle = try returnCurrentBundleForLanguage(lang: forLanguage)
}catch {
currentBundle = Bundle(path: getPathForLocalLanguage(language: "en"))!
}
}
}
/////
import Foundation
public final class RuntimeLocalizable {
public typealias LanguageKey = String
public typealias Language = Dictionary<String, String>
public typealias Translations = Dictionary<LanguageKey, Language>
let tableName: String
let translations: Translations
static let bundleName = "RuntimeLocalizable.bundle"
let manager = FileManager.default
lazy var bundlePath: URL = {
let documents = URL(fileURLWithPath: NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first!)
print("\n DIRECTORY: \(documents.absoluteString)\n")
let bundlePath = documents.appendingPathComponent(RuntimeLocalizable.bundleName, isDirectory: true)
return bundlePath
}()
public init(translations: Translations, name: String) {
tableName = name
self.translations = translations
}
func clean() throws {
// TODO: There can be multiple table names in the same Bundle. So only remove the bundle if there is no more string files.
var langFiles: Dictionary<String, Int> = [:]
for item in manager.enumerator(at: bundlePath, includingPropertiesForKeys: nil, options: [.skipsPackageDescendants])! {
print(item)
}
if manager.fileExists(atPath: bundlePath.path) {
try manager.removeItem(at: bundlePath)
}
}
public func bundle() throws -> Bundle {
if manager.fileExists(atPath: bundlePath.path) == false {
try manager.createDirectory(at: bundlePath, withIntermediateDirectories: true, attributes: nil)
}
for language in translations {
let lang = language.key
let langPath = bundlePath.appendingPathComponent("\(lang).lproj", isDirectory: true)
if manager.fileExists(atPath: langPath.path) == false {
try manager.createDirectory(at: langPath, withIntermediateDirectories: true, attributes: nil)
}
let sentences = language.value
let res = sentences.reduce("", { $0 + "\"\($1.key)\" = \"\($1.value)\";\n" })
let filePath = langPath.appendingPathComponent("\(tableName).strings")
let data = res.data(using: .utf32)
manager.createFile(atPath: filePath.path, contents: data, attributes: nil)
print(res)
}
let localBundle = Bundle(url: bundlePath)!
return localBundle
}
}
///////////
func localized() -> String {
return NSLocalizedString("entertainment_header", tableName: "", bundle: LocalizationManager().currentBundle, value: "", comment: "")
}