iOS 本地自动打包工具

作者: smalldu | 来源:发表于2016-08-17 13:12 被阅读2760次
自动打包

1、为什么要自动打包工具?

每修改一个问题,测试都让你打包一个上传fir , 你要clean -> 编译打包 -> 上传fir -> 通知测试。而且打包速度好慢,太浪费时间了。如果有一个工具能自动的帮你做完上面所有的事情,岂不是快哉?

2、网上有那么多自动打包工具,我直接下载就行了为啥还要学习?

没错网上有很多打包工具,包括github上也有一些直接从github下载并打包上传的,但是他们的不一定适合你,首先下载下来要配置各种参数,不会配,还有网上大多是针对普通项目,但是我们项目是cocoaPods管理的,编译的是 xxx.xcworkspace 不是 xxx.xcodeproj 。怎么办 , xxx.xcodeproj 自动编译后就在你项目目录下会有 xxx.app 但是 xxx.xcworkspace 找不到怎么办?怎么指定目录 , 这些网上的库大都没有的。

3、需要哪些准备工作?

首先你得有装xcode , python3.5 (我装的版本,其他版本也行), 待打包的项目。安装相关软件,随便搜索下就可以了。

废话结束,开始正文。本文介绍的是自动clean本地项目,编译 打包 上传fir 邮件通知相关人员。不涉及从git上下载。原理就是利用python执行控制台命令。对
iOS项目进行打包

xcode控制台命令

xcode 控制台命令基本都是以 xcodebuild 开头的介绍几个简单的命令,大家可以在命令行试试。

  • xcodebuild -version 查看xcode的版本号和build的版本号
  • xcodebuild -showsdks 显示当前系统的SDK、及其版本
  • xcodebuild -listcd 到工程目录下执行此命令 显示target Schemes

没有使用 cocoaPods 项目的编译

如果你的项目是普通的项目没有使用cocoaPods 那么 cd 到工程目录下直接执行 xcodebuild build ,就会自动编译了 参数都是默认 默认build release。
你也可以指定 xcodebuild -configuration debug build build的时候会在你工程目录下生成一个build文件夹,build/Release-iphoneos/xx.app
就是一会打包成ipa需要的文件。 第一次build速度会比较慢,要把编译环境拉下来,不要删除build文件夹,以后build 速度就会变快。

使用了 cocoaPods 项目的编译

如果不幸你也和我一样使用了cocoaPods , 其实也没啥不幸的 ,只是编译的时候就比较麻烦了 ,首先还是 cd 到项目目录 。但是你要指定编译文件和 scheme
而且还要指定build后build文件夹的位置,如果位置找不到,后面怎么自动打包ipa?。

我这里的命令大概是这样的:
xcodebuild -workspace xxx.xcworkspace -scheme 你的scheme -configuration debug -derivedDataPath 指定路径 ONLY_ACTIVE_ARCH=NO
这样就能正常编译并把build指定到我们想要去的目录

打包ipa

打包ipa只要上面路径对了,打包指定从.app 文件的路径 , 打包到你指定地方就行了。
命令:
xcrun -sdk iphoneos PackageApplication -v 这里填.app的路径 -o 指定存放ipa路径/文件名.ipa

python实现篇

上面只是说了下编译的原理,下面看下怎么通过python自动处理这些任务 。

clean、编译、打包

首先创建一个xxx.py文件,需要你懂点python 语法,不懂就直接copy代码。不要改tab 。python的语法是严格按照tab区分的。后面我会放上我的代码,你们改改
变量就可以使用。

首先你需要引入一些外部依赖。设置编码为utf-8

# -*- coding: utf-8 -*-
import os
import sys
import time
import hashlib
from email import encoders
from email.header import Header
from email.mime.text import MIMEText
from email.utils import parseaddr, formataddr
import smtplib

第一步 , 声明一些变量

# 项目根目录
project_path = "/Users/xx/project"
# 编译成功后.app所在目录
app_path = "/Users/xx/project/build/Build/Products/Release-iphoneos/xxx.app"
# 指定项目下编译目录
build_path = "build"
# 打包后ipa存储目录
targerIPA_parth = "/Users/xx/Desktop"

第二步,clean,和创建一个文件夹,这里的示例是针对有使用cocoaPods的项目 , 如果没有使用 不用创建文件夹 ,命令自行简化

# 清理项目 创建build目录
def clean_project_mkdir_build():
    os.system('cd %s;xcodebuild clean' % project_path) # clean 项目
    os.system('cd %s;mkdir build' % project_path) # 创建目录

%s 是py的占位符,字符串类型。后面是真正的填充。

第三步编译项目

def build_project():
    print("build release start")
    os.system ('cd %s;xcodebuild -list')
    os.system ('cd %s;xcodebuild -workspace xxx.xcworkspace  -scheme xxx -configuration release -derivedDataPath %s ONLY_ACTIVE_ARCH=NO || exit' % (project_path,build_path))

不知道scheme是啥的xcodebuild -list 自己查

第四步 打包

# 打包ipa 并且保存在桌面
def build_ipa():
    global ipa_filename
    ipa_filename = time.strftime('yourproject_%Y-%m-%d-%H-%M-%S.ipa',time.localtime(time.time()))
    os.system ('xcrun -sdk iphoneos PackageApplication -v %s -o %s/%s' % (app_path,targerIPA_parth,ipa_filename))

然后你现在再编写个方法,按顺序调用就可以编译打包了 ,执行完会看到桌面的ipa

def main():
    # 清理并创建build目录
    clean_project_mkdir_build()
    # 编译coocaPods项目文件并 执行编译目录
    build_project()
    # 打包ipa 并制定到桌面
    build_ipa()

执行就在最下面直接调用就行了 main()

上传fir

我们是把代码上传到fir测试的,如果你们用的蒲公英或者其他,请自行搜索。
通过 gem install fir-cli 如果你没有ruby环境,自行搜索

安装完成后,在命令行输入fir 回车 。会有fir的命令提示。我们上传fir需要fir的API_TOKEN , 去fir官网登录找好就能找到。
拿到那一串串字符,在变量区加上

# firm的api token
fir_api_token = "xxxxxxxxxxxxxxxxxxxxxxxxxx"

然后命令传入ipa目录和token就可以上传了

#上传
def upload_fir():
    if os.path.exists("%s/%s" % (targerIPA_parth,ipa_filename)):
        print('watting...')
        # 直接使用fir 有问题 这里使用了绝对地址 在终端通过 which fir 获得
        ret = os.system("/usr/local/bin/fir p '%s/%s' -T '%s'" % (targerIPA_parth,ipa_filename,fir_api_token))
    else:
        print("没有找到ipa文件")

这里也有遇到一个=坑,就是在终端直接fir 带后面的就可以执行 ,但是在这里识别不了命令,必须制定全路径,怎么找命令的全路径呢?终端输入 which fir

发邮件

具体发邮件功能看代码,这里有几个变量。我使用的是新浪邮箱发的,smtp服务器 , 如果你是 pop3 请更换,还要在邮箱里开启相应的服务

from_addr = "xxxx@sina.com"
password = "*****"
smtp_server = "smtp.sina.com"
to_addr = 'aaa@qq.com,bbbb@qq.com'

然后发邮件的方法

我们的fir路径是固定的

# 发邮件
def send_mail():
    msg = MIMEText('xxx iOS测试项目已经打包完毕,请前往 http://fir.im/xxxxx 下载测试!', 'plain', 'utf-8')
    msg['From'] = _format_addr('自动打包系统 <%s>' % from_addr)
    msg['To'] = _format_addr('xxx测试人员 <%s>' % to_addr)
    msg['Subject'] = Header('xxx iOS客户端打包程序', 'utf-8').encode()
    server = smtplib.SMTP(smtp_server, 25)
    server.set_debuglevel(1)
    server.login(from_addr, password)
    server.sendmail(from_addr, [to_addr], msg.as_string())
    server.quit()

然后执行顺序是这样的

def main():
    # 清理并创建build目录
    clean_project_mkdir_build()
    # 编译coocaPods项目文件并 执行编译目录
    build_project()
    # 打包ipa 并制定到桌面
    build_ipa()
    # 上传fir
    upload_fir()
    # 发邮件
    send_mail()

# 执行
main()

本文重点在自动打包命令上,python代码感兴趣的可以去Python教程 学习。
本文代码已经托管在github上:https://github.com/smalldu/autoipa
文章同步放在我的blog上:iOS 本地自动打包工具

相关文章

网友评论

  • tztTzt:楼主,问下下载下来配置好 还是运行xcodebuild build命令吗
  • 灵儿菇凉:您好,我按您的脚本打出来的包比xcode打出来的大了一倍呢??求解。xcode只有14M 用脚本打的30多M
  • 小小土豆dev:sh: /usr/local/bin/fir: No such file or directory
    能问下,这个是什么原因吗?搜了下,用这个命令export PATH=$PATH:/usr/local/bin,但问题还存在。
    小小土豆dev:刚看了下是这里的问题
    # 直接使用fir 有问题 这里使用了绝对地址 在终端通过 which fir 获得
    ret = os.system("/usr/local/bin/fir p '%s/%s' -T '%s'" % (targerIPA_parth,ipa_filename,fir_api_token))
  • 1ea6ca9222a5:博主在吗,我通过这个脚本成功打包上传到fir了,上边显示是企业级的,下载不了,下载的时候显示“xxx”coule not be installed at this time... 我在Xcode code signing 那儿指定了证书
    python脚本里边也修改了 os.system ('cd %s;xcodebuild -workspace YuLinZhengFeng.xcworkspace -scheme YuLinZhengFeng -configuration release -derivedDataPath %s ONLY_ACTIVE_ARCH=NO CODE_SIGN_IDENTITY iPhone Distribution:YuLinZhengFeng_dis || exit' % (project_path,build_path)) 还是不行 , 是不是这儿写的有问题 怎么解决啊 :sweat:
    JasonEVA:@shuaiOS 你看看是不是用脚本打包出来的.ipa文件比用xcode打包出来的.ipa文件小一点
    1ea6ca9222a5:@大石头布 按照你说的改了,重新打包一次还是企业版的,还提示下载不了 :sweat: , 证书什么的也指定好了,我刚才又用xcode 打包一下上传fir了,内测版的就可以下载。
    smalldu:@shuaiOS building setting 中看下 Provisioning Profile 有没有指定证书 ,那里指定 应该就可以,不要用Auto ,然后 python脚本就不用改了
  • Lilin_Coder:hi博主,如果我xcode中选的开发证书,在Python中编译的时候 加上CODE_SIGN_IDENTITY = “企业证书”,这样能成功编译吗
    smalldu:@Lilin_Coder building setting 中看下 Provisioning Profile 有没有指定证书 ,那里指定 应该就可以,不要用Auto , 试试
  • 未来主义者:# 项目根目录
    project_path = "/Users/xx/project"
    # 编译成功后.app所在目录
    app_path = "/Users/xx/project/build/Build/Products/Release-iphoneos/zuber.app"
    # 指定项目下编译目录
    build_path = "build"
    # 打包后ipa存储目录
    targerIPA_parth = "/Users/xx/Desktop"
    这些都是要替换成自己的吗??
    还有就是证书如何配置呀?? :joy:
    smalldu:@唐磊光 更改了什么
    未来主义者:@大石头布 谢谢回复, 我配置之后可以打出包了,但是我在项目中更改一些东西后,打出的包怎么还是更改前的包呀 :flushed:
    smalldu:@唐磊光 这些是要替换,证书不配置应该可以
  • JavenWang:fir命令行就可以构建 用不着这么麻烦 还有难道大家都不用fastlane么
    smalldu:@JavenWang fir所有命令
    fir build_apk BUILD_DIR # Build Android app (alias: `...
    fir build_ipa BUILD_DIR [options] [settings] # Build iOS app (alias: `bi`).
    fir help # Describe available commands...
    fir info APP_FILE_PATH # Show iOS/Android app info, ...
    fir login # Login fir.im (aliases: `l`).
    fir mapping MAPPING_FILE_PATH # Upload app mapping file to ...
    fir me # Show current user info if u...
    fir publish APP_FILE_PATH # Publish iOS/Android app to ...
    fir upgrade # Upgrade fir-cli and quit (a...
    fir version # Show fir-cli version number...

    Options:
    -T, [--token=TOKEN] # User's API Token at fir.im
    -L, [--logfile=LOGFILE] # Path to writable logfile
    -V, [--verbose], [--no-verbose] # Show verbose
    # Default: true
    -q, [--quiet], [--no-quiet] # Silence commands
    -h, [--help], [--no-help] # Show this help message and quit

    最多有个打包,那个是clean和编译?
    JavenWang:@大石头布 你需要看看fir和fastlane帮助文档
    smalldu:@JavenWang fir命令行可以clean 编译 打包iOS项目?fastlane提交AppStore的 我们是每次测试版本的发布。
  • xxttw:mark
  • zenon:我也觉得应该一切ok的,毕竟都上传到fir了。
    因为我看资料,如果不做额外设置,那就用xcode默认的。

    如果自动打包时,要制定证书配置该怎么做的?
    我目前的Code Signing Identity都是选择的iPhone Developer。
    Provisioning Profile是Automaic。
    zenon:@大石头布 谢谢作者您的帮助,Xcode改automatic为指定的就OK了
    smalldu:@土土土土土土 要么你不要auto指定下 要么加编译和打包的指令加参数 CODE_SIGN_IDENTITY 一般是iPhone Distribution:xxxxx
    smalldu:@土土土土土土 我没选auto,是指定的
  • zenon:博主你好,谢谢你的分享。
    我用了你的python脚本。已经成功打包上传到fir。
    但是下载时,提示无法安装。
    不知道会是因为为什么问题?手动打包出来,是没有问题的。就是脚步打包后有问题。
    smalldu:@土土土土土土 无法安装?是不是证书配置问题,我这边一切OK呀
  • 孙先生的PlanB:上传之后是企业版, 想问石头大师如何变成 内测版本的...
    smalldu:@孙先生的PlanB 恩 , 就给后面加参数
    孙先生的PlanB:@大石头布 是脚本里面改嘛?
    smalldu:@孙先生的PlanB 编译和压缩打包的时候可以指定证书参数是 CODE_SIGN_IDENTITY 一般是iPhone Distribution:xxxxx 你可以试试
  • c97db3ba215a:请问这个脚本怎么用啊?对这个完全不懂啊。。
    smalldu:@_Mrmua 自动clean 编译 打包 上传fir 发邮件给测试人员
  • 红烧大鸡腿:上面的命令行打包试了之后总是失败。提示无法创建ipa文件([zip I/O error: No such file or directory
    zip error: Could not create output file (BOCHK_Mortgage_Build/BOCHK_Mortgage_UAT.ipa))
    smalldu:@HCX_IOS 首先 你要cd到你项目的根目录 然后执行 xcodebuild clean 就可以clean了 , 然后你不是cocoaPods项目直接 xcodebuild -configuration debug build 就可以编译了,再然后 xcrun -sdk iphoneos PackageApplication -v 这里你app的目录,就是根目录下会生成build文件夹 -o 目标目录 $ARCHIVE_PATH这是什么鬼没用的指定绝对目录, 命令一条一条执行 所有命令都是cd到根目录执行的 , 我文章说的很清楚呀。不知道你为什么没理解
    红烧大鸡腿:帮忙看一下哪里可能写错了?
    xcodebuild clean -project "../BOCHK_Mortgage.xcodeproj" -scheme "BOCHK_Mortgage_$ENV" -configuration "debug" build "$ARCHIVE_PATH/BOCHK_Mortgage.app"

    xcrun -sdk iphoneos PackageApplication -v "$ARCHIVE_PATH/BOCHK_Mortgage.app" -o "$ARCHIVE_PATH/BOCHK_Mortgage_$ENV.ipa"
    smalldu:@HCX_IOS No such file or directory 没有这个目录 , 我是直接放在桌面的 第一 你放的那个目录有没有?第二、你编译好的app文件的目录对不对 。 自己检查下,没有的话 创建好,或者在 代码里用mKdir 创建
  • 红烧大鸡腿:命令行打包能否写成一个完整的脚本文件?上面所写只是写了一个大概,并不完整,连打包证书以及授权文件都没有加进去 :smile:
    smalldu:@HCX_IOS 代码已经上传github了 ,地址上面也贴了,你直接下载
    红烧大鸡腿:还是有问题,对脚本这一块不熟,能否将你的脚本文件代码发我邮箱13632697164@163.com
    smalldu:@HCX_IOS 打包是完整的呀,你下载代码修改参数就能运行,这个脚本我一直在用,证书难道编译的时候不会自己读配置文件
  • 李国安:这个东西好 回头试一下! 粗略的看了一遍! 有些疑问!
    smalldu:@CristianoRLong 有问题提出来,尽量帮你解决

本文标题:iOS 本地自动打包工具

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