前言
在iOS項(xiàng)目開發(fā)的過(guò)程中,如果版本迭代開發(fā)的時(shí)間比較長(zhǎng),那么在很多版本開發(fā)以后或者說(shuō)有多人開發(fā)參與以后,工程中難免有一些垃圾資源,未被使用卻占據(jù)著api包的大?。?
這里我通過(guò)Python腳本來(lái)查找項(xiàng)目中未被使用的圖片、音頻、視頻資源,然后刪除掉;以達(dá)到減小APP包大小的目的!
代碼
先查找項(xiàng)目中所以的資源文件存到你數(shù)組里面
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)
遍歷查詢項(xiàng)目的所以代碼,查找工程中所引用的資源文件
# 查詢項(xiàng)目的所以代碼
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里面的,一部分是直接導(dǎo)入工程目錄中的資源,如果是Assets.xcassets垃圾資源直接刪除就行了,但是如果是直接導(dǎo)入到工程目錄里面的資源,那就先刪除project.pbxproj中的引用,再刪除本地資源文件;
# 刪除無(wú)用的資源文件
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)
# 直接導(dǎo)入到工程中的圖片需要?jiǎng)h除project.pbxproj中的引用,再移除本地文件
def delResAtProjectPbxproj():
global _projectPbxprojPath, _resNameMap, _hadDelMap
if _projectPbxprojPath != None:
# 先把需要?jiǎng)h除的資源名先保存一份
_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()
# 已經(jīng)清理過(guò)project.pbxproj中的引用的資源文件,開始從_resNameMap中移除已被處理過(guò)的資源文件
# 并刪除本地的對(duì)應(yīng)的資源文件
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
總的調(diào)用函數(shù)
# 開始清理無(wú)用的垃圾資源文件
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 + '需要?jiǎng)h除的資源文件' + '-' * 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開發(fā)程序員沒有Python基礎(chǔ),這里做了一個(gè)圖形化操作界面,歡迎大家下載使用!
下載地址:
https://gitee.com/zfj1128/ZFJ...
軟件截圖:
更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主
微信掃碼或搜索:z360901061

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