Swift:用命令行工具转.strings为.csv及SwiftGen API可行性与最优方案咨询
转换Localizable.strings到CSV:Swift命令行工具实现+SwiftGen方案解析
嘿,我刚好折腾过本地化文件格式转换的需求,来给你详细说说可行的方案:
一、用Swift命令行工具手动实现转换
如果你想快速实现,不依赖第三方库,可以自己写一个轻量的Swift命令行程序来完成转换。核心思路是读取.strings文件,解析键值对,再按照CSV格式输出。
这里给你一个可用的实现示例:
import Foundation func convertStringsToCSV(stringsPath: String, csvPath: String) throws { // 读取目标.strings文件内容 let content = try String(contentsOfFile: stringsPath, encoding: .utf8) let lines = content.components(separatedBy: .newlines) var csvRows = ["Key,Value"] // CSV表头 for line in lines { let trimmedLine = line.trimmingCharacters(in: .whitespacesAndNewlines) // 跳过空行和注释行 guard !trimmedLine.isEmpty, !trimmedLine.starts(with: "//") else { continue } // 解析键值对(处理带双引号的标准格式) guard let separatorRange = trimmedLine.range(of: " = ") else { continue } let key = String(trimmedLine[..<separatorRange.lowerBound]).trimmingCharacters(in: ["\""]) let valuePart = String(trimmedLine[separatorRange.upperBound...]) // 清理值末尾的分号和引号 let value = valuePart.replacingOccurrences(of: ";", with: "").trimmingCharacters(in: ["\""]) // 处理值中的逗号(CSV规则:含逗号的字段需要用双引号包裹) let escapedValue = value.contains(",") ? "\"\(value)\"" : value csvRows.append("\(key),\(escapedValue)") } // 将结果写入CSV文件 let csvContent = csvRows.joined(separator: "\n") try csvContent.write(toFile: csvPath, atomically: true, encoding: .utf8) } // 处理命令行参数 guard CommandLine.arguments.count == 3 else { print("使用方式:swift run StringToCSVConverter <Localizable.strings路径> <输出CSV路径>") exit(1) } let stringsPath = CommandLine.arguments[1] let csvPath = CommandLine.arguments[2] do { try convertStringsToCSV(stringsPath: stringsPath, csvPath: csvPath) print("转换成功!CSV文件已保存到:\(csvPath)") } catch { print("转换失败:\(error.localizedDescription)") }
使用方法:
- 创建一个Swift包(
swift package init --type executable) - 把上面的代码替换到
Sources/[你的包名]/main.swift中 - 执行
swift run StringToCSVConverter /path/to/Localizable.strings /path/to/output.csv即可完成转换
二、SwiftGen API能否完成这个操作?
SwiftGen本身的核心定位是生成代码来便捷访问本地化字符串,原生并没有直接提供.strings转CSV的功能,但我们可以借助它的底层解析能力来实现——毕竟SwiftGen需要解析各种本地化文件格式,它的解析模块已经处理了很多复杂场景(比如多行字符串、占位符、特殊字符等)。
实现步骤:
- 在你的Swift包的
Package.swift中添加SwiftGen依赖:
dependencies: [ .package(url: "https://github.com/SwiftGen/SwiftGen.git", from: "6.6.0") ], targets: [ .executableTarget( name: "StringsToCSV", dependencies: [.product(name: "SwiftGenCore", package: "SwiftGen")] ) ]
- 编写转换代码:
import SwiftGenCore import Foundation func convertWithSwiftGen(stringsPath: String, csvPath: String) throws { // 使用SwiftGen的解析器读取.strings文件 let parser = try StringsParser(path: stringsPath) let entries = parser.entries var csvRows = ["Key,Value"] for entry in entries { guard let value = entry.value else { continue } // 处理CSV的逗号转义 let escapedValue = value.contains(",") ? "\"\(value)\"" : value csvRows.append("\(entry.key),\(escapedValue)") } let csvContent = csvRows.joined(separator: "\n") try csvContent.write(toFile: csvPath, atomically: true, encoding: .utf8) } // 命令行参数处理 guard CommandLine.arguments.count == 3 else { print("使用方式:swift run StringsToCSV <Localizable.strings路径> <输出CSV路径>") exit(1) } let stringsPath = CommandLine.arguments[1] let csvPath = CommandLine.arguments[2] do { try convertWithSwiftGen(stringsPath: stringsPath, csvPath: csvPath) print("转换成功!CSV文件已保存到:\(csvPath)") } catch { print("转换失败:\(error.localizedDescription)") }
这种方式的优势在于,SwiftGen的解析器已经经过了充分测试,能处理各种 edge case,比自己写的解析逻辑更健壮。
三、最优解决方案选择
根据你的使用场景来选:
- 偶尔转换,需求简单:优先用手动实现的Swift命令行工具,轻量、无依赖,快速就能搞定。
- 频繁处理本地化文件,或需要支持复杂格式:选择基于SwiftGen解析模块的方案,它能处理多行字符串、占位符、特殊字符等复杂情况,减少手动编写解析逻辑的bug。
内容的提问来源于stack exchange,提问作者birdy
相关产品推荐
相关产品推荐

