前言
在iOS項目開發的過程中,如果版本迭代開發的時間比較長,那么在很多版本開發以后或者說有多人開發參與以后,工程中難免有一些垃圾資源,未被使用卻占據著api包的大小!
這里我通過Python腳本來查找項目中未被使用的圖片、音頻、視頻資源,然后刪除掉;以達到減小APP包大小的目的!
代碼
先查找項目中所以的資源文件存到你數組里面
def searchAllResName(file_dir):
global _resNameMap
fs = os.listdir(file_dir)
for dir in fs:
tmp_path = os.path.join(file_dir, dir)
if not os.path.isdir(tmp_path):
if isResource(tmp_path) == True and '/Pods/' not in tmp_path and '.appiconset' not in tmp_path and '.launchimage' not in tmp_path:
imageName = tmp_path.split('/')[-1].split('.')[0]
_resNameMap[imageName] = tmp_path
conLog.info_delRes('[FindRes OK] ' + tmp_path)
elif os.path.isdir(tmp_path) and tmp_path.endswith('.imageset') and '/Pods/' not in tmp_path:
imageName = tmp_path.split('/')[-1].split('.')[0]
_resNameMap[imageName] = tmp_path
conLog.info_delRes('[FindRes OK] ' + tmp_path)
else:
searchAllResName(tmp_path)
遍歷查詢項目的所以代碼,查找工程中所引用的資源文件
# 查詢項目的所以代碼
def searchProjectCode(file_dir):
global _projectPbxprojPath
fs = os.listdir(file_dir)
for dir in fs:
tmp_path = os.path.join(file_dir, dir)
if tmp_path.endswith('project.pbxproj'):
_projectPbxprojPath = tmp_path
if not os.path.isdir(tmp_path):
if '/Pods/' not in tmp_path:
try:
findResNameAtFileLine(tmp_path)
conLog.info_delRes('[ReadFileForRes OK] ' + tmp_path)
except Exception as e:
pass
# conLog.error_delRes('[ReadFileForRes Fail] [' + str(e) + ']' + tmp_path)
else:
searchProjectCode(tmp_path)
# 查找工程中所引用的資源文件
def findResNameAtFileLine(tmp_path):
global _resNameMap
Ropen = open(tmp_path,'r')
for line in Ropen:
lineList = line.split('"')
for item in lineList:
# bar@2x barimg.png
if item in _resNameMap or item.split('.')[0] in _resNameMap or item + '@1x' in _resNameMap or item + '@2x' in _resNameMap or item + '@3x' in _resNameMap:
del _resNameMap[item]
Ropen.close()
刪除垃圾資源文件,這里垃圾資源文件刪除分為兩部分一部分是Assets.xcassets里面的,一部分是直接導入工程目錄中的資源,如果是Assets.xcassets垃圾資源直接刪除就行了,但是如果是直接導入到工程目錄里面的資源,那就先刪除project.pbxproj中的引用,再刪除本地資源文件;
# 刪除無用的資源文件
def delAllRubRes():
global _resNameMap, _hadDelMap
# .imageset類型的資源圖片直接刪除
for resName in list(_resNameMap.keys()):
tmp_path = _resNameMap[resName]
if tmp_path.endswith('.imageset'):
if os.path.exists(tmp_path) and os.path.isdir(tmp_path):
try:
# 已刪除的元素
_hadDelMap[resName] = tmp_path
# 刪除.imageset文件夾
delImagesetFolder(tmp_path)
# 字典移除
del _resNameMap[resName]
conLog.info_delRes('[DelRubRes OK] ' + tmp_path)
except Exception as e:
conLog.error_delRes('[DelRubRes Fail] [' + str(e) + ']' + tmp_path)
else:
conLog.error_delRes('[DelRubRes Fail] [not exists] ' + tmp_path)
delResAtProjectPbxproj()
def delImagesetFolder(rootdir):
filelist = []
filelist = os.listdir(rootdir)
for f in filelist:
filepath = os.path.join( rootdir, f )
if os.path.isfile(filepath):
os.remove(filepath)
elif os.path.isdir(filepath):
shutil.rmtree(filepath,True)
shutil.rmtree(rootdir,True)
# 直接導入到工程中的圖片需要刪除project.pbxproj中的引用,再移除本地文件
def delResAtProjectPbxproj():
global _projectPbxprojPath, _resNameMap, _hadDelMap
if _projectPbxprojPath != None:
# 先把需要刪除的資源名先保存一份
_needDelResName = []
file_data = ''
Ropen = open(_projectPbxprojPath,'r')
for line in Ropen:
idAdd = True
for resName in _resNameMap:
if resName in line:
idAdd = False
if resName not in _needDelResName:
_needDelResName.append(resName)
if idAdd == True:
file_data += line
Ropen.close()
Wopen = open(_projectPbxprojPath,'w')
Wopen.write(file_data)
Wopen.close()
# 已經清理過project.pbxproj中的引用的資源文件,開始從_resNameMap中移除已被處理過的資源文件
# 并刪除本地的對應的資源文件
for item in _needDelResName:
tmp_path = _resNameMap[item]
if os.path.exists(tmp_path) and not os.path.isdir(tmp_path):
# 已刪除的元素
_hadDelMap[item] = tmp_path
# 刪除文件
os.remove(tmp_path)
# 字典移除
del _resNameMap[item]
conLog.info_delRes('[DelRubRes OK] ' + tmp_path)
else:
pass
總的調用函數
# 開始清理無用的垃圾資源文件
def startCleanRubRes(file_dir, ignoreList = []):
global _resNameMap, _hadDelMap,_isCleaing
if _isCleaing == True:
return
_isCleaing = True
initData()
conLog.info('-' * 30 + '開始清理資源文件' + '-' * 30)
searchAllResName(file_dir)
conLog.info_delRes('-' * 20 + '全部的資源文件列表' + '-' * 20)
conLog.info_delRes(_resNameMap)
for item in ignoreList:
if item in list(_resNameMap.keys()):
del _resNameMap[item]
conLog.info_delRes('-' * 20 + '忽略刪除的資源文件' + '-' * 20)
conLog.info_delRes(ignoreList)
searchProjectCode(file_dir)
conLog.info_delRes('-' * 20 + '需要刪除的資源文件' + '-' * 20)
conLog.info_delRes(_resNameMap)
delAllRubRes()
conLog.info_delRes('-' * 20 + '刪除成功的資源文件' + '-' * 20)
conLog.info_delRes(_hadDelMap)
conLog.info_delRes('-' * 20 + '刪除失敗的資源文件' + '-' * 20)
conLog.info_delRes(_resNameMap)
_isCleaing = False
軟件
鑒于有些iOS開發程序員沒有Python基礎,這里做了一個圖形化操作界面,歡迎大家下載使用!
下載地址:
https://gitee.com/zfj1128/ZFJ...
軟件截圖:
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
