使用Python脚本半自动化iOS企业版包更新
背景
在我之前一篇文章里 iOS企业内部应用分发 讲述了 iOS 企业帐号打包的 ipa
分发,但是如果每次 ipa
更新,重新上传 *.ipa
后还要手动编辑 *.plist
的新的 ipa
的 url
和包的相关信息,这就和打包一样(使用 fastlane),是毫无技术含量但是花时间的事情,作为一个爱偷懒的人,我总是想利用自身所学或者一些工具来代替我做一些重复又没技术含量的事,在本文涉及的这件事里,显然,脚本要派上用场,最终选用了 Python
而没有用 Bash
—- 从 ipa
读取相关信息并写入到目的 plist
。Python
只是业余,如您有建议或改进,欢迎留言评论指出,感激不尽!
直接上代码
#!/usr/bin/python3
#coding:utf-8
import zipfile, plistlib, sys, re, os.path, io
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')
global plist_root # Info.plist
global ipa_name # ipa 名称
def analyze_ipa_with_plistlib(ipa_path):
global plist_root
ipa_file = zipfile.ZipFile(ipa_path)
plist_path = find_plist_path(ipa_file)
plist_data = ipa_file.read(plist_path)
plist_root = plistlib.loads(plist_data)
print_ipa_info (plist_root)
def find_plist_path(zip_file):
name_list = zip_file.namelist()
pattern = re.compile(r'Payload/[^/]*.app/Info.plist')
for path in name_list:
m = pattern.match(path)
if m is not None:
return m.group()
def print_ipa_info(plist_root):
print ('\n' + '源 ipa 包信息:')
CFBundleDisplayName = ''
isCFBundleDisplayNameExist = True
try:
CFBundleDisplayName = plist_root['CFBundleDisplayName']
except:
print ('CFBundleDisplayName 不存在,将获取 CFBundleName')
isCFBundleDisplayNameExist = False
if isCFBundleDisplayNameExist != True:
try:
CFBundleDisplayName = plist_root['CFBundleName']
except:
print ('CFBundleName 不存在')
print ('Display Name: %s' % CFBundleDisplayName)
print ('Bundle Identifier: %s' % plist_root['CFBundleIdentifier'])
print ('Version: %s' % plist_root['CFBundleShortVersionString'] + '\n')
def print_plist_info(plist_path, beforeWritten):
dict = plistlib.readPlist(plist_path)
metadata = dict["items"][0]["metadata"]
softwarePackageDict = dict["items"][0]["assets"][0]
state = "前" if beforeWritten else "后"
print ('写入' + state +'的plist信息')
print ('bundle-identifier: %s' % metadata['bundle-identifier'])
print ('bundle-version: %s' % metadata['bundle-version'])
print ('title: %s' % metadata['title'])
print ('ipa url: %s' % softwarePackageDict['url'] + '\n')
def writeToPlist(plist_path):
global plist_root
# 读取app.plist
dict = plistlib.readPlist(plist_path)
CFBundleDisplayName = ''
isCFBundleDisplayNameExist = True
try:
CFBundleDisplayName = plist_root['CFBundleDisplayName']
except:
print ('CFBundleDisplayName 不存在,将获取 CFBundleName')
isCFBundleDisplayNameExist = False
if isCFBundleDisplayNameExist != True:
try:
CFBundleDisplayName = plist_root['CFBundleName']
except:
print ('CFBundleName 不存在')
# 更改包信息
metadata = dict["items"][0]["metadata"]
metadata['bundle-identifier'] = plist_root['CFBundleIdentifier']
metadata['bundle-version'] = plist_root['CFBundleShortVersionString']
metadata['title'] = CFBundleDisplayName
# 更改ipa地址
softwarePackageDict = dict["items"][0]["assets"][0]
# 生成新的 ipa 路径
global ipa_name
url = softwarePackageDict['url']
urlComArr = url.split('/')
# 删除文件名
urlComArr.pop() # 删除最后一个
urlComArr.append(ipa_name) # 拼接新文件名及扩展名
newUrlComArrStr = '/'.join(urlComArr) # Array to String
softwarePackageDict['url'] = newUrlComArrStr
plistlib.writePlist(dict, plist_path) # 写入plist
if __name__ == '__main__':
args = sys.argv[1:]
if len(args) != 2:
print ('参数错误,用法: python3 config.py /path/to/ipa /path/to/plist')
sys.exit(0)
global ipa_name
ipa_path = args[0]
analyze_ipa_with_plistlib(ipa_path)
ipa_name = os.path.basename(ipa_path)
plist_path = args[1]
print_plist_info(plist_path, True)
writeToPlist (plist_path)
print_plist_info(plist_path, False)
说明
每次新打包后,需要更新 plist
文件相关信息,直接在服务器或者本地运行该脚本便可更新 plist
信息,然后覆盖服务器上的同名文件即可(亲手实践过 ipa
分发就没困惑),但运行该脚本的系统应该安装了 Python3
,否则无法运行。用法如下,选你的终端执行:
python3 config.py appName.ipa路径 app.plist路径