在混淆代码的时候,要在func.plist文件中配置需要混淆的函数名和变量名。整个项目工程的代码量太大,不可能手动将所有的函数名和变量名添加到func.plist中,所以写了一个工程来获取整个项目工程中的函数名和变量名。
实现流程如下图
判断是否是文件夹
func isDirectory(path:String) ->Bool
{
var isDir:ObjCBool=true
if FileManager.default.fileExists(atPath: path, isDirectory: &isDir)
{
return isDir.boolValue
}
else
{
return false
}
}
获取所有的文件夹地址(包括子路径下的文件夹地址)
func getAllFilePaths(path :String) -> [String]
{
var filePaths = [String]()
do{
let array =try FileManager.default.contentsOfDirectory(atPath: path)
var isDir:ObjCBool=true
for fileName in array {
let fullPath ="\(path)/\(fileName)"
if FileManager.default.fileExists(atPath: fullPath, isDirectory: &isDir) {
if isDir.boolValue{
filePaths.append(fullPath)
let paths =self.getAllFilePaths(path: fullPath)
filePaths = filePaths + paths
}
}
}
}catch{}
// print("filePaths = \(filePaths)")
return filePaths
}
获取文件夹下的所有.swift文件地址
func getAllFile(pathList : [String]) -> [String]
{
var files = [String]()
do{
for path in pathList
{
var array =try FileManager.default.contentsOfDirectory(atPath: path)
if array.count> 0 {
array =NSArray.init(array: array).pathsMatchingExtensions(["swift"])
array = array.map({"\(path)/\($0)"})
files = files + array
}
}
}catch{}
// print("fileList = \(files)")
return files
}
获取.swift文件中所有的函数名和变量名
func getMethods(path:String)->[String: [String]]
{
var methods = [String]()
var propertyNames = [String]()
do
{
let string =try String.init(contentsOfFile: path, encoding: .utf8)
// print("string \(string)")
//property
var classList : [String] = string.components(separatedBy:"class ")
classList.removeFirst()
for classStr in classList
{
var strList : [String] = classStr.components(separatedBy:"{")
let str = strList[1]
var varList : [String] = str.components(separatedBy:"var ")
varList.removeFirst()
for str in varList
{
var arr = str.split(separator:" ", maxSplits: 1, omittingEmptySubsequences:false)
arr =String(arr[0]).split(separator:":", maxSplits: 1, omittingEmptySubsequences:false)
arr =String(arr[0]).split(separator:"!", maxSplits: 1, omittingEmptySubsequences:false)
if(!self.isSpecialStr(str:String(arr[0])))
{
propertyNames.append(String(arr[0]))
}
}
var letList : [String] = str.components(separatedBy:"let ")
let List.removeFirst()
for str in letList
{
let arr = str.split(separator:" ", maxSplits: 1, omittingEmptySubsequences:false)
if(!self.isSpecialStr(str:String(arr[0])))
{
propertyNames.append(String(arr[0]))
}
}
}
// print("propertys \(propertyNames)")
//method
var funcList : [String] = string.components(separatedBy:"func ")
funcList.removeFirst()
for str in funcList
{
letarr = str.split(separator:"(", maxSplits: 1, omittingEmptySubsequences:false)
if(!self.isSpecialStr(str:String(arr[0])))
{
methods.append(String(arr[0]))
}
}
// print("methods \(methods)")
}
catch{}
return["methods": methods ,"propertyNames": propertyNames]
判断解析出来的函数名或者变量名是否是特殊字符
func isSpecialStr(str:String) ->Bool
{
let specialList = ["id":"id","weak":"weak","strong":"strong",
"awakeFromNib":"awakeFromNib",
"tableView":"tableView",
"mapping":"mapping",
"viewDidLoad":"viewDidLoad",
"viewWillAppear":"viewWillAppear",
"==":"=="]
if(specialList[str] ==nil)
{
return false
}
else
{
return true
}
}
去重
func deDuplication(arr:[String]) -> [String]
{
letset :Set =Set(arr)
returnArray(set)
}
最后的使用
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
let mainPath = "/Users/cafei/Documents/xxxProject"
letpath = [mainPath +"Login",
mainPath +"Mine",
mainPath +"Util",
mainPath +"Discover",
mainPath +"Core",
mainPath +"Base",
mainPath +"Launch"]
var list =self.getAll(paths: path)
// print("all list = \(list)")
list =self.deDuplication(arr: list)
for resultStr in list{
print("\(resultStr)")
}
}
func getAll(paths : [String]) -> [String]
{
var all = [String]()
for path in paths
{
let pathList =self.getAllFilePaths(path: path)
let fileList =self.getAllFile(pathList: pathList)
var methodList = [String]()
var propertyList = [String]()
for file in fileList
{
let dic =self.getMethods(path: file)
methodList = methodList + (dic["methods"] ?? [""])
propertyList = propertyList + (dic["propertyNames"] ?? [""])
}
all.append(contentsOf:self.deDuplication(arr: methodList))
all.append(contentsOf:self.deDuplication(arr: propertyList))
}
return all
}
将最后在控制台打印出来的resultStr列表就是指定路径下所有文件中的函数名和变量名。
网友评论