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发送邮件接收邮件示例分享
Jan 21 Python
用Python中的字典来处理索引统计的方法
May 05 Python
Python读写ini文件的方法
May 28 Python
python字典键值对的添加和遍历方法
Sep 11 Python
Python爬虫设置代理IP的方法(爬虫技巧)
Mar 04 Python
Numpy中转置transpose、T和swapaxes的实例讲解
Apr 17 Python
python导入模块交叉引用的方法
Jan 19 Python
使用Python实现毫秒级抢单功能
Jun 06 Python
Python实现序列化及csv文件读取
Jan 19 Python
基于Python数据结构之递归与回溯搜索
Feb 26 Python
python实现简单猜单词游戏
Dec 24 Python
python可视化分析的实现(matplotlib、seaborn、ggplot2)
Feb 03 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
新浪SAE云平台下使用codeigniter的数据库配置
2014/06/12 PHP
memcache一致性hash的php实现方法
2015/03/05 PHP
php校验表单检测字段是否为空的方法
2015/03/20 PHP
var与Javascript变量隐式声明
2009/09/17 Javascript
javascript 45种缓动效果 非常酷
2011/06/28 Javascript
33个优秀的 jQuery 图片展示插件分享
2012/03/14 Javascript
JSON中双引号的轮回使用过程中一定要小心
2014/03/05 Javascript
通过$(this)使用jQuery包装后的方法或属性
2014/05/18 Javascript
JS实现网页上随滚动条滚动的层效果代码
2015/11/04 Javascript
解析jQueryEasyUI的使用
2016/11/22 Javascript
微信小程序城市定位的实现实例(获取当前所在国家城市信息)
2017/05/17 Javascript
JS库之Three.js 简易入门教程(详解之一)
2017/09/13 Javascript
vue2手机APP项目添加开屏广告或者闪屏广告
2017/11/28 Javascript
详解vue 单页应用(spa)前端路由实现原理
2018/04/04 Javascript
详解vue-cli 3.0 build包太大导致首屏过长的解决方案
2018/11/10 Javascript
详解element-ui日期时间选择器的日期格式化问题
2019/04/08 Javascript
浅谈layui 绑定form submit提交表单的注意事项
2019/10/25 Javascript
javascript实现贪吃蛇经典游戏
2020/04/10 Javascript
python实现DNS正向查询、反向查询的例子
2014/04/25 Python
python os.path模块常用方法实例详解
2018/09/16 Python
Python3爬虫学习入门教程
2018/12/11 Python
django页面跳转问题及注意事项
2019/07/18 Python
详解用python计算阶乘的几种方法
2019/08/14 Python
利用Python自动化操作AutoCAD的实现
2020/04/01 Python
丝芙兰中国官方商城:SEPHORA中国
2018/01/10 全球购物
英国马匹装备和马术用品购物网站:Equine Superstore
2019/03/03 全球购物
英国床垫和床架购物网站:Bedman
2019/11/04 全球购物
澳大利亚顶级美发和美容贸易超市:glamaCo
2020/01/19 全球购物
网上常见的一份Linux面试题(多项选择部分)
2015/02/07 面试题
公务员年总结的自我评价
2013/10/25 职场文书
保护母亲河倡议书
2014/04/14 职场文书
大班上学期幼儿评语
2014/04/30 职场文书
信息工作经验交流材料
2014/05/28 职场文书
应急管理培训方案
2014/06/12 职场文书
大学迎新标语
2014/06/26 职场文书
2015新生加入学生会自荐书
2015/03/24 职场文书