iOS开发:如何读取Localizable.strings并获取所有翻译键
如何读取Localizable.strings文件的全部内容获取所有翻译键
我来帮你搞定这个问题!你之前的代码找不到目标文件,主要是因为路径的写法不对——Bundle.main.path(forResource:)的第一个参数应该是纯文件名,不能带路径前缀。咱们一步步修正,同时给你两种高效获取所有翻译键的方案:
第一步:正确获取对应语言的Bundle
先确保能拿到目标语言(比如西班牙语es)的语言包Bundle,这是后续操作的基础:
guard let languageBundlePath = Bundle.main.path(forResource: "es", ofType: "lproj"), let languageBundle = Bundle(path: languageBundlePath) else { // 处理语言包获取失败的情况 let alert = UIAlertController(title: "Erreur".localized, message: "语言包未找到".localized, preferredStyle: .alert) alert.addAction(UIAlertAction(title: "Ok".localized, style: .cancel)) self.present(alert, animated: true) return }
方案一:直接加载为字典(最简便)
系统提供了localizedStringDictionary属性,可以直接把Localizable.strings转换成键值对字典,不需要自己解析字符串:
if let localizableDict = languageBundle.localizedStringDictionary { // 遍历所有翻译键值对 for (key, translatedValue) in localizableDict { print("翻译键:\(key),对应译文:\(translatedValue)") } } else { let alert = UIAlertController(title: "Erreur".localized, message: "Localizable.strings加载失败".localized, preferredStyle: .alert) alert.addAction(UIAlertAction(title: "Ok".localized, style: .cancel)) self.present(alert, animated: true) }
方案二:读取原始文件并解析(适合自定义处理)
如果你需要处理原始的.strings文件内容(比如保留注释、处理特殊格式),可以先读取文件字符串再手动解析:
// 从语言Bundle中获取Localizable.strings的路径 guard let stringsFilePath = languageBundle.path(forResource: "Localizable", ofType: "strings") else { let alert = UIAlertController(title: "Erreur".localized, message: "Localizable.strings未找到".localized, preferredStyle: .alert) alert.addAction(UIAlertAction(title: "Ok".localized, style: .cancel)) self.present(alert, animated: true) return } do { // 读取文件内容 let fileContent = try String(contentsOfFile: stringsFilePath, encoding: .utf8) // 按行分割并解析 let lines = fileContent.components(separatedBy: .newlines) let keyValuePairs = lines.compactMap { line -> (key: String, value: String)? in let trimmedLine = line.trimmingCharacters(in: .whitespacesAndNewlines) // 跳过空行和注释行 guard !trimmedLine.isEmpty, !trimmedLine.starts(with: "//") else { return nil } // 分割键和值(适配"key" = "value";的标准格式) let components = trimmedLine.components(separatedBy: " = ") guard components.count == 2 else { return nil } // 去除引号和分号,处理转义字符 let key = components[0].trimmingCharacters(in: CharacterSet(charactersIn: "\"")).replacingOccurrences(of: "\\\"", with: "\"") let value = components[1].trimmingCharacters(in: CharacterSet(charactersIn: "\";")).replacingOccurrences(of: "\\\"", with: "\"") return (key, value) } // 遍历解析后的键值对 for pair in keyValuePairs { print("翻译键:\(pair.key),对应译文:\(pair.value)") } } catch { let alert = UIAlertController(title: "Erreur".localized, message: "无法读取文件:\(error.localizedDescription)".localized, preferredStyle: .alert) alert.addAction(UIAlertAction(title: "Ok".localized, style: .cancel)) self.present(alert, animated: true) }
为什么你的原始代码会失败?
你之前的代码把lproj路径和文件名拼接后传给path(forResource:),但这个方法的设计逻辑是:第一个参数是文件名,第二个参数是文件类型,不需要手动拼接路径。正确的做法是先拿到语言Bundle,再从这个Bundle内部获取目标文件的路径。
内容的提问来源于stack exchange,提问作者PascalS
相关产品推荐
相关产品推荐

