美文网首页iOS开发iOS开发者iOS开发必修课
Python实现iOS自动化打包详解

Python实现iOS自动化打包详解

作者: Qinz | 来源:发表于2018-04-04 15:25 被阅读11085次
    Qinz

    可能是最简单的iOS自动化打包方式:无需手动配置证书,无需填写配置文件名称,更无需配置Bundle Identifer,总之无需很多繁琐配置,让打包流程一句命令完成!下面将会分享两种打包方式,一种是快速打包(打包时间就在一眨眼),一种是基于shenzhen(速度会比较慢),都实现了一行命令完成打包并上传蒲公英!

    一:基于编译的打包

    这种打包方式应该是目前所有打包方式中最快的,就是编译工程--找到.app文件--新建Payload文件夹--拷贝.app到Payload文件夹--压缩成zip--更改后缀名为ipa--完成!

    • 1.我们演示过程如下图:


      手动打包
    • 2.其实上面的打包过程快的话2分钟左右可以完成,作为一个追求效率的攻城狮,怎么可能满足在此,而基于测试包的频繁性,我们肯定不想一直做这样重复性而没多少技术含量的工作,接下来,我们就把这个过程自动化!


      自动化打包1

    在上图中,我们只需要执行python脚本,可以看到桌面很快生成了一个ProgramBag的文件夹,打开文件夹,彩蛋就在里面了!由于我写的脚本里包含了上传蒲公英的代码,这个包有28.3M,网络不太好会影响上传时间,真正的打包时间是可以忽略不记的,也就是执行脚本,敲击回车就好了的事!

    自动化打包2

    这里我们将打好的包自动上传到蒲公英网站,完成后自动打开下载地址,这个过程在网络好的条件下2分钟左右完成,99.9%的时间是发在上传包上!这里上传完成会自动打开到下载的网页。

    • 3.演示过程完毕,接下来我们就来看看原理是怎么实现的吧!下面开始讲解Python的具体代码~ 静心看完,相信你能看懂,说不定自己也可以很快写一个脚本,用来解决平常重复性的工作。下面是核心打包脚本:
    #编译打包流程
    def bulidIPA():
        mkdir(PayLoadPath)
        #将app拷贝到PayLoadPath路径下
        commands.getoutput('cp -r %s %s'%(appFileFullPath,PayLoadPath))
        #在桌面上创建packBagPath的文件夹
        commands.getoutput('mkdir -p %s'%packBagPath)
        #将PayLoadPath文件夹拷贝到packBagPath文件夹下
        commands.getoutput('cp -r %s %s'%(PayLoadPath,packBagPath))
        #删除桌面的PayLoadPath文件夹
        commands.getoutput('rm -rf %s'%(PayLoadPath))
        #切换到当前目录
        os.chdir(packBagPath)
        #压缩packBagPath文件夹下的PayLoadPath文件夹夹
        commands.getoutput('zip -r ./Payload.zip .')
        print "\n*************** 打包成功 *********************\n"
        #将zip文件改名为ipa
        commands.getoutput('mv Payload.zip Payload.ipa')
        #删除payLoad文件夹
        commands.getoutput('rm -rf ./Payload')
    

    有没有似曾相识的感觉?看绿色文字的部分,其实就是liunx命令,通过脚本包装了一层,可以理解为我们以前在terminal手动输入的命令,现在是自动帮我们输入并执行了,大大解放了我们的双手!

     #将app拷贝到PayLoadPath路径下
        commands.getoutput('cp -r %s %s'%(appFileFullPath,PayLoadPath))
    

    我们来分析上面这一句,我用OC的伪代码来实现的话对应下面这句:所以上面的%s相当于OC中的%@,是一种格式符,后面的appFileFullPath代表我们工程的.app存放的路径,PayLoadPath代表我们在桌面上新建的PayLoad文件路径

    copy("%@,%@",A,B)
    

    然后结合注释(自恋下:注释写的还算挺详细的)基本上代码的执行过程我们就一目了然了,至于前面的commands.getoutput是基于commands组件的命令,理解为可以在terminal执行命令即可,下面有一句代码需要说明:这是一句切换当前目录的命令

     os.chdir(packBagPath)
    

    等价于

    commands.getoutput('cd %s'%packBagPath)
    

    不要问我为什么没有用下面的命令,那是因为这句命令我这边执行不成功,被坑了很久,至于原因,还不知道为什么(如果你解决了,欢迎骚扰我),所以用上面python提供的命令代替了。

    • 4.至此,我们将第一步的手动打包过程实现了自动话,如果不需要上传蒲公英,上面的9行命令就够用了!接下来我们实现上传蒲公英的脚本:
    #上传蒲公英
    def uploadIPA(IPAPath):
        if(IPAPath==''):
            print "\n*************** 没有找到对应上传的IPA包 *********************\n"
            return
        else:
            print "\n***************开始上传到蒲公英*********************\n"
            url='http://www.pgyer.com/apiv1/app/upload'
            data={
                'uKey':USER_KEY,
                '_api_key':API_KEY,
                'installType':'2',
                'password':'',
                'updateDescription':"测试自动化打包"
            }
            files={'file':open(IPAPath,'rb')}
            r=requests.post(url,data=data,files=files)
    
    def uploadIPA(IPAPath):
    表示定义了一个函数uploadIPA,接受一个参数
    

    requests是一个网络请求的组件,我们可以把它类比为AFNetWorking,data是要传递的参数,files是要传递的文件,至于上传的参数key都是根据蒲公英提供的API来写的。上面的password代表安装app时所需要的密码,同时还有两个参数,USER_KEY和API_KEY,在蒲公英应用的位置可以找到,如图:


    KEY说明
    • 5.最后一步就是上传成功,帮我们自动打开下载页:
    def openDownloadUrl():
        webbrowser.open(r'https://www.pgyer.com/manager/dashboard/app/40c633aa8dc0ba15191632860558825e',new=1,autoraise=True)
        print "\n*************** 更新成功 *********************\n"
    

    webbrowser也是一个组件库,这些组件库在使用时,和OC一样,都要先import,里面的地址代表蒲公英上应用的地址,拷过来粘贴即可!

    • 6.整体的脚本就完了,最后在使用时配置下面的几个参数即可,一次配置,永久使用!
    appFileFullPath = '/Users/Qinz/Library/Developer/Xcode/DerivedData/DDDS-bcghxucdqelptddawpsfmvjtoefm/Build/Products/Debug-iphoneos/DDDS.app'
    PayLoadPath = '/Users/Qinz/Desktop/Payload'
    packBagPath = '/Users/Qinz/Desktop/ProgramBag'
    
    #上传蒲公英
    USER_KEY = "61ded40a68axxxxxxe9fd278acd2"
    API_KEY = "a4fe2724dc6d8cxxxxxxf1994eec219e"
    

    上图中appFileFullPath就是我们工程文件中.app的地址,至于PayLoadPath和packBagPath只需要你将"Qinz"用户名修改为你自己电脑的用户名即可!
    下图演示快速设置appFileFullPath的过程:


    appFileFullPath

    到此,第一种自动化打包方式讲解完毕!

    二:基于shenzhen打包,shenzhen是一个打包相关的库,使用也非常方便,比第一中打包方式还要少一个路径配置,当然打包的速度相对比较慢,要使用下面的脚本,首先得安装shenzhen,具体可参考https://github.com/nomad/shenzhen

    def buildIpa():
        start = time.time()
        print "\n*************** IPA包生成中 *********************\n"
         #commands.getoutput('ipa build')  #使用shenzheng打包ipa
        p = subprocess.Popen('ipa build', shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
        for line in p.stdout.readlines():
            print line,
        retval = p.wait()
    
        end = time.time()
        print "--------- 打包耗时:%s秒 ---------"%(end-start)
        print "\n*************** IPA包生成成功,准备上传蒲公英 *********************\n"
    

    这里我主要是将shenzhen的打包命令"ipa build"封装在pythone脚本中,同时记录了打包的时间,经过测试打包的时间在4~7分钟左右,这个脚本中只需要配置蒲公英的USER_KEY和API_KEY,然后cd到当前工程目录,执行脚本即可!打包成功会在当前工程目录下生成ipa包和符号化文件!使用如下:


    脚本打包

    这里的描述日志是更新到蒲公英的填写的更新日志,最后打包完成记录如下,同时也是支持蒲公英上传的,最后完成如图:


    image.png WechatIMG30.jpeg

    可以看到,打包时间耗时将近5分钟,在我看来时间还是有点长的,所以要想快速打包测试,使用第一种方式能提高不少工作效率!

    踩坑之旅:完成这个脚本的过程中,可以说是一部心酸史,一把辛酸泪,踩了不少坑(主要是之前不懂脚本),网上很多关于自动化打包的文章,下载下来执行后就没成功过,有的是需要配置一些参数,繁琐的不像自动化,目前很流行的自动化打包库fastlane,在我使用时,按照官方的教程打包就没有一次成功过,还有就是报错后都不知道怎么解决,打包就像碰运气,心里完全没底,可以说被折磨的体无完肤,经过多次失败的经历后,我决定要自己撸一个脚本,于是学习下Python脚本的语法,也就有了现在的这个版本!关于AppStore的包,还是建议使用Xcode打包!

    最后,附上这两个脚本的下载地址:
    iOS自动化打包脚本:https://github.com/ys323945/iOSAutoPage/tree/master

    备注:

    有一位简友在该脚本的基础上完善了发送邮件的功能,希望能有更多的简友帮助改善并不断升级该脚本,可以第一时间发送简信给我,我会最终整合最实用的功能更新至github仓库,方便大家使用,同时会在此放置作出贡献的简友博客地址。

    我是Qinz,希望我的文章对你有帮助。

    相关文章

      网友评论

      • SoaringHeart:ProgramBag文件夹没找到dSYM文件
      • Beyond_JG:能自动截取二维码发到qq群就好了
      • ae657405bffd:我在github提交了一个请求,楼主瞅瞅呗哈哈哈~
      • 翀鹰精灵:我的路径已经修改了 运行脚本出现以下错误:
        Traceback (most recent call last):
        File "/Users/allison/Downloads/iOSAutoPage-master/AutoPage/DaoBao.py", line 5, in <module>
        import requests
        ImportError: No module named requests
        翀鹰精灵:@Qinz “先要安装pip,然后用pip安装request网络请求库,这个涉及到python环境的安装,先找度娘搜索pip的安装教程”---看来下这个 但是如果我不需要上传蒲公英 只需要IPA包 知不是就不需要这个request网络请求库了
        翀鹰精灵:@Qinz 五楼的评论看来 你说如果只需要IPA包,网络那块注释掉即可,我把网络的注释了 但是又包了如下的错误:
        Traceback (most recent call last):
        File "/Users/allison/Downloads/iOSAutoPage-master/AutoPage/DaoBao.py", line 5, in <module>
        import requests
        ImportError: No module named requests
        Qinz:请参考5楼评论即可解决问题
      • 翀鹰精灵:我想问下 步骤1.我们演示过程如下图:
        这个打包属于什么类型的打包 ,只要手机UUID加入公司账号下即可么?
        Qinz:第一种打的是测试包,加入UDID的手机可以安装测试,证书用自动管理证书即可,关注证书的疑问可以参考我的另一篇文章 《iOS开发之带你玩转xcode自动管理证书》
      • 一洼世界:你好,请教一个问题 第一种方式
        1 、build的时候 ,scheme 的run 模式要不要修改为Release ?
        2、 执行完脚本,蒲公英也更新正常,但是app 显示 "无法下载app 此时无法下载“xxx‘"
        Qinz:@荒原W 第一种打包方式主要用于测试分发,选择debug模式也可以的 针对下载不了按照以下方式排查
        检查以下几项是否完成:1、保证打包选择的不是模拟器 2、保证证书正确配置,一般用自动证书管理即可,如果对自动证书管理不熟悉,可以参考我的博客中有一篇讲解自动证书管理的 3确保udid已经添加 4、确保手动编译了(针对第二种打包方式不需要)
      • 大牛在郑州:执行:能帮看下什么问题嘛,sudo gem install shenzhen
        ERROR: While executing gem ... (Gem::FilePermissionError)
        You don't have write permissions for the /usr/bin directory.
        大牛在郑州:@NiuNaruto 已ok
        大牛在郑州:@Qinz 已解决谢谢,用第一种打包成功了,但是第二种报错:xcrun: error: unable to find utility "xcodebuild", not a developer tool or in PATH
        error: undefined method `<' for nil:NilClass. Use --trace to view backtrace
        Qinz:请参考18楼评论即可解决你的问题
      • Zz7777777:还存在一个问题 通过人工打包才28兆 结果通过你这个大包出来的ipa结果是33.7兆
        Zz7777777:@Qinz 你的意思是在测试的时候用这个包给测试的人员测试 上架的时候 还得人工洛
        Qinz:也有会出现比Archive打的包小的情况,相差不是太大都属正常
        Qinz:@HelloKids 这种打包时没有做优化的,通过Archive打的包Xcode做了优化,该打包方式主要用于测试分发,在提高打包效率上和优化上会有所取舍的
      • Qson1:发现自动打包比手动打的包小好多 手动60M 自动 34M
        Qinz:这个相差有点大!如果打的包不能安装,按照下面过程重新配置下:选择Generic iOS Device,然后编译,将脚本中的路径重新再配置下,第一种方式的最后一张动态图演示了路径的配置
      • Zz7777777:jiangpengdeMacBook-Pro:~ jiangpeng$ python /Users/jiangpeng/Desktop/iOSAutoPage-master/DaoBao.py
        Traceback (most recent call last):
        File "/Users/jiangpeng/Desktop/iOSAutoPage-master/DaoBao.py", line 5, in <module>
        import requests
        ImportError: No module named requests
        Qinz:请查看5楼的评论内容就可以解决的
      • Zz7777777:Traceback (most recent call last):
        File "/Users/jiangpeng/Desktop/iOSAutoPage-master/AutoPage/DaoBao.py", line 86, in <module>
        des = input("请输入更新的日志描述:")
        File "<string>", line 1
        测试下demo
        ^
        SyntaxError: invalid syntax
        Qinz:@别人家的程序猿 这个和熟不熟悉python关系不大的,只是简单的终端操作,输入的时候注意以字符串的形式输入就好,如 "修复了首页的bug" 记得加上英文双引号!
        ae657405bffd:我觉得这里很有必要加入不需要输入“”的功能。不然的话,还没有学python,不知道怎么加,楼主你觉得呢?
        Qinz:输入的时候要以字符串的形式输入,如 "修复了首页的bug" 记得加上英文双引号
      • 无意惹东风:你好,看到你的文章按照这个demo实验了下,但是报错说NameError: global name 'mkdir' is not defined, 然后就手动在桌面创建了Payload文件夹注释了mkdir那句话,成功了。想问一下为什么会出现这个错误,不是很懂,望回
        Qinz:@别那么较真嘛 :+1:
        无意惹东风:@Qinz 你好,哈哈,机智的我把你原来的那句mkdir(PayLoadPath) 改成了commands.getoutput('mkdir -p %s'%PayLoadPath) ,然后就成功了,谢谢你啊
        Qinz:@别那么较真嘛 这个可能和调用顺序有关系,mkdir是定义的一个函数,执行时没有找到,代码已经优化更新到github,下载最新代码运行即可
      • e0a1b49891fa:大神 为什么更新了版本号 也更新成功 为什么在蒲公英里面没有最新的呢
        Qinz:@黑猫AK :scream: 我这边测试都是没问题的!
        1、打包之前确保已经对工程进行了编译,如果没有编译,打包的jpa就是上一次工程的
        2、去蒲公英网站检查上传的时间是不是最新的
        e0a1b49891fa:@Qinz 但是二维码都是之前的 没有最新的 感觉根本没有把打包好的最新ipa发布
        Qinz:1、检查脚本配置蒲公英的key等信息是否正确
        2、蒲公英的版本号和xcode中的版本号没多大关系,蒲公英的是自增的版本号,测试分发无需太关心版本号,正式上线注意即可!
      • 那年我们十八:你好 我想问一下 我用那种压缩方式打出来的ipa 装不了在手机上怎么办
        Qinz:@那年我们十八 选择Generic iOS Device,然后编译,将脚本中的路径重新再配置下,第一种方式的最后一张动态图演示了路径的配置
        那年我们十八:@Qinz 都没问题的 打出来的包 放在pp助手上安装显示越狱包,然后就安装不了
        Qinz:检查以下几项是否完成:1、保证打包选择的不是模拟器 2、保证证书正确配置,一般用自动证书管理即可,如果对自动证书管理不熟悉,可以参考我的博客中有一篇讲解自动证书管理的 3确保udid已经添加 4、确保手动编译了(针对第二种打包方式不需要)
      • Code_zhou:老哥,请我我就是正常的企业账号配置,怎么用这个打包之后蒲公英上提示“该应用未签名,仅可以通过越狱设备安装”.咋回事?(平常上传企业包都是这个固定的配置)
        Qinz:@Code_zhou 该脚本的第一种不适合企业账号,请使用第二种方式
      • Real_young:你好 想问一下,有没有脚本可以直接把ipa包直接传到itunes connet 后台的
        Qinz:@real_young 正式发布建议还是手动处理,我之前用fastlan测试上传到itunes成功了,然后就是一个测试的应用显示在上面,删也不好删掉~ 所以对脚本不熟悉和没有把控的情况下强烈建议手动上传
        Real_young:@Qinz 这个我装了,然后就没有然后了...
        Qinz:@real_young 可以研究下fastlan
      • 自由帝:如果更换证书或者bundle ID 如何操作?
        Qinz:@不自由的自由 这个可以研究下fastlan,可以实现你的需求
        自由帝:@Qinz 我的意思是在这脚本运行打包之前,通过脚本修改bundel ID及证书等。不是通过手动去设置,也不是通用符的那种证书,比如测试证书和发布证书之间切换。
        Qinz:@不自由的自由 更换证书和bundle ID是不影响打包的,打包的脚本是通用的,更换了证书就要配置好相关的UDID,可以直接用XCode自动管理证书即可,如果对自动证书管理不熟悉,可以参考我的另一篇文章《iOS开发之带你玩转Xcode自动管理证书》,至于bundel ID换了就相当于是换了一个应用了的
      • 天蓬大元:大佬,为什么直接改压缩文件后缀,上传蒲公英成功,但下载去显示“无法下载”呢
        Qinz:@天蓬大元 1、保证打包选择的不是模拟器 2、保证证书正确配置,一般用自动证书管理即可,如果对自动证书管理不熟悉,可以参考我的博客中有一篇讲解自动证书管理的 3确保udid已经添加 4、确保手动编译了(针对第二种打包方式不需要)
      • codeLufei:这个可以用于cocoapods的吗
        Qinz:@codeLufei 当然可以
      • 鞋底没纹易摔跤:有些地方不是很懂,像这个用app文件压缩然后改后缀名的方式是不是和 那个免证书打包ipa文件是一样的?像文章第一种方式打包到蒲公英好像是没经过证书打包的,那么别的手机能下载测试吗?不是说苹果证书里包含udid的设备才能安装这个ipa吗?希望赐教
        Qinz:@鞋底没纹易摔跤 对于个人和公司开发者账号必须要加入了udid的手机才能进行安装,企业证书不需要,同时企业证书不适合这种改名压缩的方式,而我们大部分的证书还是以个人和公司开发者账号为主的
        Qinz:@鞋底没纹易摔跤 @鞋底没纹易摔跤 要测试分发一定要证书的,用xcode自动管理证书就行,关注证书的疑问可以参考我的另一篇文章 《iOS开发之带你玩转xcode自动管理证书》
      • 鞋底没纹易摔跤:提示错误:
        Traceback (most recent call last):
        File "/Users/ljm/Desktop/巨头仓库/Karui/build.py", line 4, in <module>
        import requests
        ImportError: No module named requests
        环境:mac, 完全没接触过python
        鞋底没纹易摔跤:@Qinz 都安装好了,能运行了,但到 ‘请输入更新的日子描述’ 那里具体是什么意思?我输入testtest报错:
        Traceback (most recent call last):
        File "/Users/ljm/Desktop/build.py", line 80, in <module>
        des = input("请输入更新的日志描述:")
        File "<string>", line 1, in <module>
        NameError: name 'testtest' is not defined
        Qinz:@鞋底没纹易摔跤 如果只需要打包不需要上传蒲公英,把网络那块注释掉就行
        Qinz:@鞋底没纹易摔跤 先要安装pip,然后用pip安装request网络请求库,这个涉及到python环境的安装,先找度娘搜索pip的安装教程
      • 韩大大大:攒👍🏻
        想问下大神,在多Target下,如何实现一步到位打所有的包?
        Qinz:针对多Target的打包问题,不同的Target编译后所生成了的.app路径不同,在脚本中配置多个对应的路径,然后循环路径,将文件名改为可变的路径文件名,循环导出即可!
      • Qinz:基于python2.7和python3.6的打包脚本均已经上传github,根据实际环境使用
      • Qinz:赞👍

      本文标题:Python实现iOS自动化打包详解

      本文链接:https://www.haomeiwen.com/subject/smykhftx.html