#!/usr/bin/swift
import Foundation
class GenStrings {
let fileManager = NSFileManager.defaultManager()
let acceptedFileExtensions = ["swift", "strings"]
let excludedFolderNames = ["Carthage"]
let excludedFileNames = ["genstrings.swift"]
var regularExpresions = [String:NSRegularExpression]()
let localizedRegex = "(?<=\")([^\"]*)(?=\".(localized|localizedFormat))|(?<=(Localized|NSLocalizedString)\\(\")([^\"]*?)(?=\")"
let keyRegex = "(?<=\")([^\"]*)(?=\" =)"
let pathExtension = "lproj"
var resourcesPathName = ""
var resourcesPath:NSURL? = nil//资源文件路径
var addStringFilePath = ""//追加字符串目标文件路径
//let addStringFilePath = NSBundle.mainBundle().pathForResource("Localizable", ofType: "strings")!
var newStrings:String? = String()//最新的语言字符串集
//获取文件路径
func getFilePaths(){
let fileManager = NSFileManager.defaultManager()
var root:NSURL? = nil
root = NSURL(fileURLWithPath:fileManager.currentDirectoryPath)
let rootPath = String(root)
print(String(root))
let index = rootPath.startIndex.advancedBy(7)
rootPath = rootPath.substringFromIndex(index)
resourcesPathName = rootPath + "resources/"
addStringFilePath = rootPath + "resources/zh-Hans.lproj/Localizable.strings"
resourcesPath = NSURL(string: resourcesPathName )
}
enum GenstringsError:ErrorType {
case Error
}
///系统当前时间
func createNowDate()->String{
let date = NSDate()
let timeFormatter = NSDateFormatter()
timeFormatter.dateFormat = "yyy-MM-dd HH:mm"
return timeFormatter.stringFromDate(date) as String
}
//获取已存在的语言文件
func getExistLocalizableFile() -> [String] {
//获取当前文件根路径的所有子文件路径集合
let allFiles = fetchFilesInFolder(resourcesPath!, pathExtension: pathExtension)
print("资源文件数: \(allFiles.count)")
//装载文件名
var localizableStrings = Set()
//遍历文件
for filePath in allFiles {
let stringsInFile = keyStringsInFile(filePath)
//获取所在文件字符串的并集合,即去掉重复的
localizableStrings = localizableStrings.union(stringsInFile)
}
// We sort the strings
//排序整理字符串,按字母排序
let sortedStrings = localizableStrings.sort({ $0 < $1 })
return sortedStrings
}
func keyStringsInFile(filePath: NSURL) -> Set {
if let fileContentsData = NSData(contentsOfURL: filePath), let fileContentsString = NSString(data: fileContentsData, encoding: NSUTF8StringEncoding) {
do {
let localizedStringsArray = try regexMatches(keyRegex, string: fileContentsString as String).map({fileContentsString.substringWithRange($0.range)})
return Set(localizedStringsArray)
} catch {}
}
return Set()
}
//把最新最新的语言字符串写到本地.Strings文件中
func writeToLocalizableStringsInFile() ->Void{
/// 没有新增最新的语言字符串停止执行
if newStrings!.isEmpty{
return
}
let fileHandle = NSFileHandle(forUpdatingAtPath: addStringFilePath as String)
fileHandle?.seekToEndOfFile()
//写入时间
let date = "\n/****************************** 新增于: " + createNowDate() + " ************************/\n"
let stringDate = date.dataUsingEncoding(NSUTF8StringEncoding)
fileHandle?.writeData(stringDate!)
//写入最新的语言字符串
let stringData = newStrings!.dataUsingEncoding(NSUTF8StringEncoding)
fileHandle?.writeData(stringData!)
fileHandle?.closeFile()
}
// Performs the genstrings functionality
func perform1() {
//获取文件路径
getFilePaths()
let fileManager = NSFileManager.defaultManager()
var root:NSURL? = nil
root = NSURL(fileURLWithPath:fileManager.currentDirectoryPath)
print(String(root))
//获取当前文件根路径/Users/imac/Documents/code/bter_app/resources/
//项目的根绝对路径(这是我的项目文件路径,根据自己的项目文件路径修改)
let rootPath = NSURL(string: "/Users/imac/Documents/code/xxx/")
//获取当前文件根路径的所有子文件路径集合
let allFiles = fetchFilesInFolder(rootPath!)
// We use a set to avoid duplicates
//装载文件名
var localizableStrings = Set()
//遍历文件
for filePath in allFiles {
let stringsInFile = localizableStringsInFile(filePath)
//获取所在文件字符串的并集合,即去掉重复的
localizableStrings = localizableStrings.union(stringsInFile)
}
//获取已存在的语言文本数组
let existStrings = getExistLocalizableFile()
// We sort the strings
//排序整理字符串,按字母排序
let sortedStrings = localizableStrings.sort({ $0 < $1 })
for string in sortedStrings {
print(string)
print(sortedStrings.count)
print(existStrings.count)
if existStrings.contains(string) {
continue
}
newStrings!.appendContentsOf("\"\(string)\" = \"\(string)\";\n")
}
//打印
print(newStrings)
//追加把最新最新的语言字符串写到本地
writeToLocalizableStringsInFile()
}
// Applies regex to a file at filePath.
func localizableStringsInFile(filePath: NSURL) -> Set {
if let fileContentsData = NSData(contentsOfURL: filePath), let fileContentsString = NSString(data: fileContentsData, encoding: NSUTF8StringEncoding) {
do {
let localizedStringsArray = try regexMatches(localizedRegex, string: fileContentsString as String).map({fileContentsString.substringWithRange($0.range)})
return Set(localizedStringsArray)
} catch {}
}
return Set()
}
//MARK: Regex
func regexWithPattern(pattern: String) throws -> NSRegularExpression {
var safeRegex = regularExpresions
if let regex = safeRegex[pattern] {
return regex
}
else {
do {
let currentPattern: NSRegularExpression
currentPattern = try NSRegularExpression(pattern: pattern, options:NSRegularExpressionOptions.CaseInsensitive)
safeRegex.updateValue(currentPattern, forKey: pattern)
self.regularExpresions = safeRegex
return currentPattern
}
catch {
throw GenstringsError.Error
}
}
}
func regexMatches(pattern: String, string: String) throws -> [NSTextCheckingResult] {
do {
let internalString = string
let currentPattern = try regexWithPattern(pattern)
// NSRegularExpression accepts Swift strings but works with NSString under the hood. Safer to bridge to NSString for taking range.
let nsString = internalString as NSString
let stringRange = NSMakeRange(0, nsString.length)
let matches = currentPattern.matchesInString(internalString, options: [], range: stringRange)
return matches
}
catch {
throw GenstringsError.Error
}
}
//MARK: File manager
func fetchFilesInFolder(rootPath: NSURL, pathExtension: String = "") -> [NSURL] {
var files = [NSURL]()
do {
let directoryContents = try fileManager.contentsOfDirectoryAtURL(rootPath, includingPropertiesForKeys: [], options: .SkipsHiddenFiles)
for urlPath in directoryContents {
if let stringPath = urlPath.path, let lastPathComponent = urlPath.lastPathComponent, let pathExtension = urlPath.pathExtension {
var isDir : ObjCBool = false
if fileManager.fileExistsAtPath(stringPath, isDirectory:&isDir) {
if isDir {
if !excludedFolderNames.contains(lastPathComponent) && pathExtension == urlPath.pathExtension {
let dirFiles = fetchFilesInFolder(urlPath)
files.appendContentsOf(dirFiles)
}
} else {
if acceptedFileExtensions.contains(pathExtension) && !excludedFileNames.contains(lastPathComponent) {
files.append(urlPath)
}
}
}
}
}
} catch {}
return files
}
}
let genStrings = GenStrings()
//genStrings.getExistLocalizableFile()
genStrings.perform1()
//genStrings.perform()
执行后的效果: