Python一键查找iOS项目中未使用的图片、音频、视频资源


Posted in Python onAugust 12, 2019

前言

在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...

软件截图:

Python一键查找iOS项目中未使用的图片、音频、视频资源

总结

以上所述是小编给大家介绍的Python一键查找iOS项目中未使用的图片、音频、视频资,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!

Python 相关文章推荐
python实现巡检系统(solaris)示例
Apr 02 Python
pycharm 使用心得(七)一些实用功能介绍
Jun 06 Python
Python使用Mechanize模块编写爬虫的要点解析
Mar 31 Python
python读取csv文件并把文件放入一个list中的实例讲解
Apr 27 Python
python发送多人邮件没有展示收件人问题的解决方法
Jun 21 Python
在交互式环境中执行Python程序过程详解
Jul 12 Python
python爬取Ajax动态加载网页过程解析
Sep 05 Python
Django 项目布局方法(值得推荐)
Mar 22 Python
在matplotlib中改变figure的布局和大小实例
Apr 23 Python
python requests包的request()函数中的参数-params和data的区别介绍
May 05 Python
python算的上脚本语言吗
Jun 22 Python
Python爬虫教程知识点总结
Oct 19 Python
django+echart数据动态显示的例子
Aug 12 #Python
Flask框架学习笔记之使用Flask实现表单开发详解
Aug 12 #Python
Flask框架学习笔记之表单基础介绍与表单提交方式
Aug 12 #Python
python内存管理机制原理详解
Aug 12 #Python
Flask框架学习笔记之路由和反向路由详解【图文与实例】
Aug 12 #Python
python实现图片压缩代码实例
Aug 12 #Python
django与vue的完美结合_实现前后端的分离开发之后在整合的方法
Aug 12 #Python
You might like
PHP array 的加法操作代码
2010/07/24 PHP
PHPMailer使用教程(PHPMailer发送邮件实例分析)
2012/12/06 PHP
PHP 7.0新增加的特性介绍
2017/06/08 PHP
php生成复杂验证码(倾斜,正弦干扰线,黏贴,旋转)
2018/03/12 PHP
Laravel 实现Controller向blade前台模板赋值的四种方式小结
2019/10/22 PHP
JS模板实现方法
2013/04/03 Javascript
JavaScript通过字典进行字符串翻译转换的方法
2015/03/19 Javascript
利用Javascript实现简单的转盘抽奖
2017/02/13 Javascript
javascript实现日期三级联动下拉框选择菜单
2020/12/03 Javascript
浅谈vue实现数据监听的函数 Object.defineProperty
2017/06/08 Javascript
bootstrap基本配置_动力节点Java学院整理
2017/07/14 Javascript
Vue.js实现价格计算器功能
2020/03/30 Javascript
基于Vue.js 2.0实现百度搜索框效果
2020/12/28 Javascript
从parcel.js打包出错到选择nvm的全部过程
2018/01/23 Javascript
在vue中使用jointjs的方法
2018/03/24 Javascript
Vue.js样式动态绑定实现小结
2019/01/24 Javascript
Vue 幸运大转盘实现思路详解
2019/05/06 Javascript
JS插入排序简单理解与实现方法分析
2019/11/25 Javascript
利用JS如何获取form表单数据
2019/12/19 Javascript
vue动态设置路由权限的主要思路
2021/01/13 Vue.js
在Python中使用zlib模块进行数据压缩的教程
2015/06/26 Python
Python实现读取文件最后n行的方法
2017/02/23 Python
python下读取公私钥做加解密实例详解
2017/03/29 Python
python 函数传参之传值还是传引用的分析
2017/09/07 Python
Python图像的增强处理操作示例【基于ImageEnhance类】
2019/01/03 Python
浅谈对pytroch中torch.autograd.backward的思考
2019/12/27 Python
Python通过类的组合模拟街道红绿灯
2020/09/16 Python
tensorflow2.0教程之Keras快速入门
2021/02/20 Python
神经网络训练采用gpu设置的方式
2021/03/03 Python
html5新增的定时器requestAnimationFrame实现进度条功能
2018/12/13 HTML / CSS
优秀党员获奖感言
2014/02/18 职场文书
个人工作表现评语
2014/04/30 职场文书
国庆节标语大全
2014/10/08 职场文书
详解java如何集成swagger组件
2021/06/21 Java/Android
分布式Redis Cluster集群搭建与Redis基本用法
2022/02/24 Redis
浅谈MySQL中的六种日志
2022/03/23 MySQL