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装饰器验证配置文件示例
Feb 24 Python
pycharm下打开、执行并调试scrapy爬虫程序的方法
Nov 29 Python
解决python3 安装完Pycurl在import pycurl时报错的问题
Oct 15 Python
Python实现FM算法解析
Jun 18 Python
Python 图像处理: 生成二维高斯分布蒙版的实例
Jul 04 Python
python实现图片九宫格分割
Mar 07 Python
python中字典按键或键值排序的实现代码
Aug 27 Python
django框架创建应用操作示例
Sep 26 Python
PyTorch使用cpu加载模型运算方式
Jan 13 Python
关于Tensorflow 模型持久化详解
Feb 12 Python
tensorflow 大于某个值为1,小于为0的实例
Jun 30 Python
Python sqlalchemy时间戳及密码管理实现代码详解
Aug 01 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读取IMAP邮件
2006/10/09 PHP
谈PHP生成静态页面分析 模板+缓存+写文件
2009/08/17 PHP
PHP自动重命名文件实现方法
2014/11/04 PHP
php计算数组相同值出现次数的代码(array_count_values)
2015/01/20 PHP
YII2.0之Activeform表单组件用法实例
2016/01/09 PHP
PHP对称加密算法(DES/AES)类的实现代码
2017/11/14 PHP
thinkPHP框架整合tcpdf插件操作示例
2018/08/07 PHP
laravel实现于语言包的完美切换方法
2019/09/29 PHP
jqgrid 简单学习笔记
2011/05/03 Javascript
根据选择不同的下拉值出现相对应的文本输入框
2013/08/01 Javascript
NodeJS使用jQuery选择器操作DOM
2015/02/13 NodeJs
javascript比较两个日期相差天数的方法
2015/07/24 Javascript
JavaScript驾驭网页-获取网页元素
2016/03/24 Javascript
基于javascript实现最简单选项卡切换
2017/02/01 Javascript
js 奇葩技巧之隐藏代码
2017/08/11 Javascript
Nodejs 发布自己的npm包并制作成命令行工具的实例讲解
2018/05/15 NodeJs
Vue中对比scoped css和css module的区别
2018/05/17 Javascript
在 Angular6 中使用 HTTP 请求服务端数据的步骤详解
2018/08/06 Javascript
微信小程序批量监听输入框对按钮样式进行控制的实现代码
2019/10/12 Javascript
基于leaflet.js实现修改地图主题样式的流程分析
2020/05/15 Javascript
从零学Python之引用和类属性的初步理解
2014/05/15 Python
简单谈谈Python中函数的可变参数
2016/09/02 Python
TF-IDF与余弦相似性的应用(二) 找出相似文章
2017/12/21 Python
python3爬虫之设计签名小程序
2018/06/19 Python
python获取本机所有IP地址的方法
2018/12/26 Python
Python字典深浅拷贝与循环方式方法详解
2020/02/09 Python
python实现井字棋小游戏
2020/03/04 Python
浅谈Python3多线程之间的执行顺序问题
2020/05/02 Python
python实现学生管理系统开发
2020/07/24 Python
CSS3 边框效果
2019/11/04 HTML / CSS
创立科技Java面试题
2015/11/29 面试题
Ruby如何实现动态方法调用
2012/11/18 面试题
导游词欢迎词
2015/02/02 职场文书
公司与个人合作协议书
2016/03/19 职场文书
Mysql 如何批量插入数据
2021/04/06 MySQL
MySQL 表锁定 LOCK和UNLOCK TABLES的 SQL语法
2022/04/18 MySQL