背景
iOS项目废弃旧的类及方法引用,替换成新的类及新的方法, 如果调用较多, 手动替换将是一件费时费力且容易出错的事情,交给脚本就轻松多了
归根结底, 懒惰是第一生产力
实现效果
- 替换旧的方法引用为新的方法引用
- 删除旧的方法需要导入的头文件
- 新增新的方法需要导入的头文件, 放在当前类所有import的最后一行
- 同一个类不会重复导入相同的头文件
- 若和pod目录平级,不会修改pod目录下的文件
- 终端打印修改的内容和行数
使用方式
-
脚本需要放在与要替换的工程代码最外层文件夹平级
eg:
- cd该目录,执行语句
python replaceMethod.py '要废弃的方法调用' '新的方法调用' '要废弃的方法调用的头文件导入' '新的方法调用的头文件导入'
eg : 要替换 [JYUserInfoManager userToken]
引用为 JYLoginMaintUser.token
因为 [JYUserInfoManager userToken]
需要导入头文件 #import <JYModuleDeprecated/JYUserInfoManager.h>
JYLoginMaintUser.token
需要导入头文件
#import <JYModuleAccount/JYLoginMaintUser.h>
执行
python replaceMethod.py '[JYUserInfoManager userToken]' 'JYLoginMaintUser.token' '#import <JYModuleDeprecated/JYUserInfoManager.h>' '#import <JYModuleAccount/JYLoginMaintUser.h>'
脚本源码
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#0.1.0
import os
import sys
import os.path
import shutil
def main():
methodName = sys.argv[1]
newMethodName = sys.argv[2]
removeName = sys.argv[3]
importName = sys.argv[4]
print ('methodName:', methodName )
print ('newMethodName:', methodName )
print ('importName:', importName)
print ('removeName:', removeName)
# os.getcwd() 方法用于返回当前工作目录
current_path = os.getcwd()
print('ℹ️ 脚本所在路径:' + current_path)
code_files = []
#1. 找到除了Pods文件夹下的代码文件
for root, dirs, files in os.walk(current_path):
for file in files:
# 找到所有类
if os.path.splitext(file)[1] == '.m' or os.path.splitext(file)[1] == '.mm' :
code_file_path = os.path.join(root,file)
#如果文件是在pods中,就忽略掉
if code_file_path.find('/Pods/')<0:
code_files.append(code_file_path)
print('类的总数: %d' %len(code_files))
print('ℹ️ ℹ️ ℹ️ ℹ️ ℹ️ ℹ️ ℹ️ ℹ️ 获取含有' + methodName + '方法的类 ℹ️ ℹ️ ℹ️ ℹ️ ℹ️ ℹ️ ℹ️ ℹ️ ℹ️ ')
print('\n')
#2. 找到所有包含原方法的类
methodClassList = []
for code_file in code_files:
read_file = open(code_file)
file_contents = read_file.read()
read_file.close()
method_file_list = file_contents.split('\n')
for method_file in method_file_list:
if methodName in method_file:
if code_file not in methodClassList:
methodClassList.append(code_file)
print('ℹ️ 包含该方法的类:' + code_file)
print('包含该方法类的总数: %d' %len(methodClassList))
#3. 找到该方法, 替换成新的方法
for code_file in methodClassList:
read_file = open(code_file)
file_contents = read_file.readlines()
read_file.close()
write_file = open(code_file, "w")
for line in file_contents:
if methodName in line:
line = line.replace(methodName,newMethodName)
print('ℹ️ 替换:' + methodName + '为' + newMethodName)
print('-----line:' + line)
write_file.write(line)
write_file.close()
#4. 删除原本导入的头文件
for code_file in methodClassList:
read_file = open(code_file)
file_contents = read_file.readlines()
read_file.close()
write_file = open(code_file, "w")
for line in file_contents:
if removeName in line:
continue
write_file.write(line)
write_file.close()
#5.添加需要导入的头文件
for code_file in methodClassList:
read_file = open(code_file)
file_contents = read_file.read()
read_file.close()
#循环获取 #import数组
import_file_list = file_contents.split('\n')
line = 0
maxline = 0; #在最后一行import 后导入头文件
for import_file in import_file_list:
line = line + 1
if '#import' in import_file:
if maxline < line:
maxline = line;
# print('ℹ️ 包含该方法的类:' + code_file)
# print('import_file: ', import_file)
# print('行数: ', line)
print('ℹ️ 包含该方法的类:' + code_file)
checkSelfResult = checkSelf(code_file, importName)
if checkSelfResult == False:
if importName not in import_file_list:
writeinfile(code_file, importName, maxline + 1)
#判断是否是要import的类本身
def checkSelf (code_file, importName):
#导入pod中库 忽略
if '#import<' in importName.replace(" ", "") :
return False
import_class_name = importName.replace(" ", "").split('#import"')[1].split('.h')[0]
if(import_class_name in code_file):
return True
else :
return False
#写入文件
def writeinfile(path, content, line=0):
lines = []
with open(path, 'r') as r:
for l in r:
lines.append(l)
if line == 0:
lines.insert(0, '{}\n'.format(content))
else:
lines.insert(line-1, '{}\n'.format(content))
s = ''.join(lines)
with open(path, 'w') as m:
m.write(s)
print('写入 :' + content)
print('💕写入行数: %d' %line)
m.close()
if __name__ == '__main__':
main()
写在最后
完全业余写法, 仅用于限于使用, 不建议学习