├── .gitignore ├── LICENSE ├── README.md └── get_P3_picture_name.py /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2017 TalkingJourney 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 前言 2 | 如果iOS App工程中导入P3图片的话,在iOS9.3以下的设备,打开App会出现必现Crash。但是Crash只会在上传到App Store上的包出现,平时测试不易发现,所以一般会在TestFlight上进行验证,是否存在P3 Crash。缺点:需要专门的机型,有P3图片的话,手动跑命令行,手动搜索图片名,各种不便。详情情况请见:[P3图片导致iOS9.3一下崩溃问题](https://www.jianshu.com/p/97add04998ef), 3 | 4 | 毕竟UED同学会不会不小心给你P3切图,这个不好说,所以最好我们自己每次验证,做到万无一失,毕竟线上大规模Crash后果太严重。所以我写了这个python脚本,仅仅只要每次上线前运行,就能帮你确认是否有P3图片,帮你找到P3图片的名字。 5 | 6 | # 使用方法 7 | 1. 将打好的.ipa包和python脚本放在一个目录下; 8 | 2. 使用终端运行python脚本即可,即执行python name.py。(需要Mac安装python命令,没有安装的同学,请自行google安装) 9 | 10 | # 优点及缺点 11 | * 优点:运行方便,自动获得结果,快速稳定可靠,并可以同时验证多个.ipa文件; 12 | * 缺点:需要手动将.ipa文件和脚本文件放在同一个目录下,如果你们工程脚本自动化打包,可以在打包脚本中添加拷贝.ipa到脚本文件目录的命令,这个缺点就可以得到解决。 13 | 14 | # 结束 15 | 如果大家有什么想法的话,可以向我反馈。如果大家喜欢的话,也可以通过star来鼓励下我,感谢大家捧场。 16 | -------------------------------------------------------------------------------- /get_P3_picture_name.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | import os, shutil, json, zipfile 3 | 4 | def printRed(content): 5 | print("\033[31m" + content + "\033[0m") 6 | 7 | def printBlue(content): 8 | print("\033[36m" + content + "\033[0m") 9 | 10 | def delete_path(path): 11 | if os.path.exists(path): 12 | shutil.rmtree(path) 13 | return True 14 | return False 15 | 16 | 17 | def look_for_file(path, file_info): 18 | app_path = "" 19 | for root, dir_name_list, file_name_list in os.walk(path): 20 | for file_name in file_name_list: 21 | if file_name.find(file_info) != -1: 22 | return os.path.join(root, file_name) 23 | 24 | for dir_name in dir_name_list: 25 | if dir_name.find(file_info) != -1: 26 | return os.path.join(root, dir_name) 27 | app_path = look_for_file(dir_name, file_info) 28 | if app_path != "": 29 | return app_path 30 | return "" 31 | 32 | # 获取脚本路径 33 | script_path = os.path.dirname(os.path.abspath('__file__')) 34 | print "Path: " + script_path 35 | 36 | # 获取所有.ipa文件 37 | all_file_list = os.listdir(script_path) 38 | ipa_file_list = [] 39 | for file_item in all_file_list: 40 | file_splitext = os.path.splitext(file_item) 41 | if file_splitext[1] == '.ipa': 42 | ipa_file_list.append(file_splitext[0]) 43 | print "found " + file_item 44 | 45 | # 检查是否存在.ipa文件 46 | if len(ipa_file_list) == 0: 47 | printRed("not found .ipa file in " + script_path) 48 | exit(-1) 49 | 50 | for file_name in ipa_file_list: 51 | print "\n" + file_name + ":" 52 | file_path = os.path.join(script_path, file_name) 53 | 54 | # 删除之前的Payload文件夹 55 | payload_path = file_path + "_Payload" 56 | if delete_path(payload_path): 57 | print file_name + ": delete the previous " + payload_path + " file folder" 58 | 59 | # 解压.ipa文件 60 | print file_name + ": upzip " + file_name + ".ipa ..." 61 | zip_file = zipfile.ZipFile(file_name + ".ipa") 62 | if os.path.isdir(payload_path): 63 | pass 64 | else: 65 | os.mkdir(payload_path) 66 | for names in zip_file.namelist(): 67 | zip_file.extract(names, payload_path + "/") 68 | print file_name + ": upzip " + file_name + " success." 69 | 70 | # 找到.app文件 71 | print file_name + ": look for " + file_name + " .app ..." 72 | app_path = look_for_file(payload_path, ".app") 73 | if app_path == "": 74 | printRed(file_name + ": not found .app file in " + payload_path) 75 | delete_path(payload_path) 76 | continue 77 | else: 78 | print file_name + ": found .app file in " + payload_path 79 | 80 | # 找到Assets.car文件 81 | print file_name + ": look for " + file_name + " Assets.car ..." 82 | assets_path = look_for_file(app_path, "Assets.car") 83 | if assets_path == "": 84 | printRed(file_name + ": not found Assets.car in " + payload_path) 85 | delete_path(payload_path) 86 | continue 87 | else: 88 | print file_name + ": found Assets.car in " + payload_path 89 | 90 | # 将包文件中的图片信息存储到文件中 91 | print file_name + ": load picture info ..." 92 | # assets_path = os.path.join(app_path, "Assets.car") 93 | assets_json_file = os.path.join(payload_path, "Assets.json") 94 | assets_info_command = "sudo xcrun --sdk iphoneos assetutil --info " + assets_path + " > " + assets_json_file 95 | if os.system(assets_info_command) != 0: 96 | printRed(file_name + " load picture info failure") 97 | delete_path(payload_path) 98 | continue 99 | else: 100 | print file_name + ": load picture info success" 101 | 102 | # 获取图片信息 103 | print file_name + ": read picture info ..." 104 | with open(assets_json_file, 'r') as f: 105 | picture_info_list = json.load(f) 106 | print file_name + ": read picture info success" 107 | 108 | # 删除创建的文件夹 109 | delete_path(payload_path) 110 | 111 | # 获取P3图片的图片名 112 | print file_name + ": look for P3 picture ..." 113 | picture_name_list = [] 114 | for picture_info in picture_info_list: 115 | if picture_info.get("DisplayGamut") == 'P3' or picture_info.get("Encoding") == 'ARGB-16': 116 | picture_name = picture_info.get("RenditionName") 117 | picture_name_list.append(picture_name) 118 | print file_name + ": look for P3 picture success" 119 | 120 | # 检查是否存在P3图片 121 | print file_name + ": success!" 122 | print file_name + ": P3 pictures list" 123 | print "--------------" 124 | if len(picture_name_list) == 0: 125 | printBlue(file_name + ": not found P3 picture!") 126 | else: 127 | # 打印所有P3图片名 128 | for picture_name in picture_name_list: 129 | printBlue(picture_name) 130 | print "--------------" 131 | --------------------------------------------------------------------------------