当前位置:   article > 正文

IOS工程自动打包

IOS工程自动打包

IOS的开发过程中,当需要给测试人员发布测试包的时候,直接使用xcode来做的效率是非常低下的。尤其是当有一点小改动需要重新出包时,那简直是个折磨的人的工作。通过一番研究后,遂决定写一系列脚本,以代替人工完成打包和发布的过程。

目前脚本已经完成,基本可以满足我目前的需求。现将其开源,托管在github上,项目地址:点击这里

思路


借助xcode所附带的“Command Line Tools”,可以通过命令行来完成IOS工程的编译和打包工作。脚本正是基于此完成的。

本套脚本分为三个部分:负责编译工程并打包的脚本ipa-build,负责生成itms-services协议文件的脚本ipa-publish,以及负责将ipa-publish脚本生成文件上传到服务器的脚本upload。

其中,由于我自己的情况是服务器端的同事给我了内部测试服务器的sftp的上传权限,所以这个upload脚本主要实现了使用sftp来上传的功能。具体可以实际情况来做修改。

关于itms-services协议的一些内容,可以参考我之前的文章:《shell脚本实现ipa一键安装(itms-services协议)》

注意:默认安装完的xcode并没有自带“Command Line Tools”,需要在xcode中选择后下载才能使用

实现


打开工程后,会发现本套脚本中包含好几个shell文件。下面对其功能做说明:

  1. ipa-build: 编译xcode工程并生成ipa文件
  2. ipa-publish: 生成符合itms-services协议的文件,并发布到服务器。
  3. sendEmail: stmp发送email的脚本。(别人写的)
  4. sftpDownloadFile: 通过sftp协议下载文件
  5. sftpUploadFile: 通过sftp协议上传文件
  6. updateLocalIndexHtml: 对索引文件进行处理(二进制文件,非shell脚本)
  7. uploadItemsServicesFiles: 将itms-services协议文件上传到服务器

实际使用的脚本,只有"ipa-build"和"ipa-publish"这两个。其他文件会被ipa-publish这个脚本调用的依赖文件。其中出了"updateLocalIndexHtml"是我用objc写的一个用来进行文本处理的编译后的二进制文件,其余均为shell脚本。

shell脚本实现,大家可以打开脚本来看一下,里面的注释算是很详细了。不需要太多说明。

其中值得一提的就是我在写sftp协议上传功能的时候,碰到了一个问题就是使用脚本来自动输入密码,也就是交互式脚本的编写。最后选择了expect来完成,因为我发现mac系统里自带了这个expect命令。

使用


在编写脚本时,我已经考虑到,要尽量使这个脚本使用起来简单方便。如果只需要打包,那么只使用ipa-build脚本即可。如果需要用itms-services协议来发布,则再运行ipa-publish脚本即可。在ipa-publish脚本中调用了upload脚本,所以upload脚本不需要单独使用。

ipa-build脚本使用方法:

ipa-build脚本绝对路径 参数1 参数2

其中,参数1是IOS工程的根路径,是必输项。参数2可以不输入,是可选的,含义是编译时的工程configuration类型,有4种类型可选:Debug, AdHoc,Release, Distribution。默认是Release。

ipa-build脚本运行后,会在IOS工程根路径下生成名为“build”的文件夹,在这个文件夹中又有一个名为“ipa-build”的文件夹,打包所生成的最新ipa包就在其中。

ipa-publish脚本使用方法:

ipa-publish脚本绝对路径 参数1 参数2

参数1是IOS工程的根路径,是必输项。参数2是可选的,含义是当上传文件成功后是否发送email通知,y为发送,n为不发送,默认的值是不发送。

ipa-publish脚本运行后,会在“build”文件夹中生成一个以工程的targetname为名字的文件夹。其中,存放了itms-services协议所需的所有文件。脚本会将里面内容全部上传到服务器中。

注意事项


1、运行脚本需要绝对路径,不能使用相对路径。

2、脚本下载后,若要使用,有些脚本需要一些改动。

其中ipa-build脚本无须更改。可以直接使用。ipa-publish脚本需要配置一些信息后方能正常使用。

用文本打开ipa-publish脚本后,在shell开始的地方,有一段需要配置的地方,如下:

  1. #须配置内容 start
  2. #sftp参数设置
  3. sftp_server=192.168.xx.xx
  4. sftp_username=xx
  5. sftp_password=xx
  6. sftp_workpath="/usr/share/xx/xx/xx"
  7. #发布应用的url地址
  8. pulish_url="/xx"
  9. #以下是邮箱的相关设置
  10. #收件人
  11. email_reciver=xx@xx.com
  12. #发送者邮箱
  13. email_sender=xx@xx.com
  14. #邮箱用户名
  15. email_username=xx
  16. #邮箱密码
  17. email_password=xx
  18. #smtp服务器地址
  19. email_smtphost=smtp.exmail.qq.com
  20. #可配置内容 end

根据实际情况配置即可。

 


在具体的操作过程中可能会遇到下面的问题

could not stat active Xcode path '/Volumes/Xcode/Xcode.app/Contents/Developer'. (No such file or directory)


解决办法:

xcode-select -switch 新的xcode路径

sudo xcode-select --switch /Applications/Xcode.app/Contents/Developer



安装command line tools for xcode

其实这个很好找,但是网上很多误导人的文章,很让人不爽。

打开xcode以后,点击菜单栏的:

Xcode -> Preferences… ->  Downloads

这时候你应该就可以看到Command Line tools了,在Components选项卡里。其实ios模拟器也是这里安装的,大家应该可以看到。

xcode5下面安装有些改变

之前系统升级到 Mac OS X 10.9 Mavericks ,顺带的连xcode也一起升级了。

升级后我还没发现啥问题,后面因为需要用到重新编译php,就发现问题了。

各种原本能正常运行的命令,现在都出现问题

之前我还以为是编译参数问题,但是经过一系列操作后就排除了参数可能出现的错误

实在无奈的我装了一个brow后提示

1
2
3
Warning: Your Xcode (5.0) is outdated
Please install Xcode 5.0.1.
Error: No available formula for bzip2 -devel

好吧,想重装一下Command Line Tools,居然在以前的那个地方找不到了。。。

最后查询苹果开发者网站后得出答案了,原来新的Command Line Tools跟Java一样变成了在线可选安装包,直接图形化安装就可以了。

运行命令

1
sudo xcode- select -- install

就会显示一行文字,并且弹出一个对话框,确认安装后他就会自己下载来安装了。

至此,Command Line Tools就能够重新复活了~~~



原文地址:http://blog.csdn.net/ccf0703/article/details/8588667

其它参考帖子:http://stblog.baidu-tech.com/?p=1295

http://3426724.blog.51cto.com/3416724/883484



通常打包采用xcodebuild和xcrun两个命令,xcodebuild负责编译,xcrun负责将app打成ipa。

 
常见步骤如下:
1、清理工程
/usr/bin/xcodebuild -target targetName clean
 
2、编译工程
/usr/bin/xcodebuild -target targetName

3、打包

/usr/bin/xcrun -sdk iphoneos PackageApplication -v path/To/xxx.app -o xxx.ipa

 如果是含签名的包,上面两个命令需要增加一些参数。

xcodebuild -target targetName CODE_SIGN_IDENTITY="iPhone Distribution:XXXXXX"
xcrun -sdk iphoneos PackageApplication -v 源app路径 -o 输出的ipa路径 --sign "iPhone Distribution:XXXXXX"


这里要重点说一下,如果脚本要带签名,最好是工程里面设置不签名如下图:

然后再在脚本带上对应的证书和签名

xcodebuild -project SanGameJJH.xcodeproj -scheme SanGameJJH -configuration Release -sdk iphoneos6.1 CONFIGURATION_BUILD_DIR=$path/ipa CODE_SIGN_IDENTITY="iPhone Developer: XXXXXXXXXXXX" build 


xcrun -sdk iphoneos PackageApplication -v "app路径" -o "ipa的输出路径" --sign "iPhone Developer: XXXXXXXX" --embed $path/dev.mobileprovision

格式有:




自动打包步骤:

1、先用xocde手动编译好一个App,假设为MyApp.app
 
2、导入证书文件到MAC的钥匙链
//创建钥匙链
security create-keychain -p myapp myapp.keychain
//解锁,否则回弹框等待输入密码
security unlock-keychain -p myapp myapp.keychain
//导入证书
security import /opt/myapp.p12 -k myapp.keychain -P mypassword -T /usr/bin/codesign

3、以MyApp.app为模板,copy一个备份,然后进行各种资源的替换,比如替换了应用的图片文件等

4、替换对应的*.mobileprovision文件到MyApp.app目录

5、删除MyApp.app下的签名信息_CodeSignature

6、修改info.plist Bundle indentifier和*.mobileprovision一致

7、修改MyApp.xcent中application-identifiervalue值为对应证书名称,可以以一个xcent为模板, 注意如果没有aps-environment关键字,打出来的ipa包将没有apns模块,格式如下:
 
复制代码
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
        <key>application-identifier</key>
        <string>Z4LR7CBRUD.com.yesun.vic</string>
        <key>aps-environment</key>
        <string>production</string>
        <key>get-task-allow</key>
        <false/>
</dict>
</plist>
复制代码

8、重签名codesign

/usr/bin/codesign --force --sign 9c8b212f6a2c2382847b104e387a01b246d4ce42 --resource-rules=MyApp.app/ResourceRules.plist --entitlements MyApp.xcent Mkey3G.app

9、生成ipa包

/usr/bin/xcrun -sdk iphoneos  PackageApplication -v MyApp.app -o MyApp.ipa  --sign  9c8b212f6a2c2382847b104e387a01b246d4ce42 --embed MyApp.app/embed.mobileprovision

10、删除钥匙链

security delete-keychain myapp.keychain

 

带xcodebuild编译的打包步骤如下:
  1. 导入钥匙链
  2. 对工程clean
  3. 修改info信息
  4. 修改project信息
  5. xcodebuild
  6. 替换各种资源文件
  7. 修改xcent
  8. 重新签名codesign
  9. xcrun打ipa
  10. 删除钥匙链




这里就以codesign这个工具的出错说明。


首先这里运行的mac系统中已经可以在Xcode中进行正常的签名app了,现在用命令的形式进行签名:

Cunz$ codesign -s "iPhone Developer" ./Test

出现了以下错误提示:

Test: User interaction is not allowed.


解决办法:

Cunz$ export CODESIGN_ALLOCATE=/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/codesign_allocate

Cunz$ security unlock-keychain

password to unlock default:

在运行签名工具就可以成功了:

Cunz$ codesign -s "iPhone Developer" ./Test


expect 脚本输入密码


应用一:
实现从普通用户“test”切换到root用户,自动输入root的密码,不用在终端提示符下执行密码输入操作。
步骤:
(1)vi autosu.sh
(2)#!    /usr/bin/expect      -f         //指定expect工具的路径,如果不清楚具体路径,可以用"which expect"命令来查看。
spawn    su   -                    //  在expect 中用"spawn"关键字来调用命令“su - ”
expect     ":"                        //在执行了su   -  命令之后,提示输入密码的提示符。例如你在执行了su - 命令之后,终端里面会出现提示“口令:”,那么你就可以在这里写expect    ":",或者expect    -exact    "口令:"
send     "rootpasswd\r"    //这里expect用send将你的root密码自动输入到上面的提示符之后。
interact                            //操作完成。

注意:这里强调一下执行脚本时要注意的地方,不能按照习惯来用sh ***.sh来这行expect的程序,会提示找不到命令,因为expect用的不是bash所以会报错。执行的时候直接./***.sh就可以了。~切 记!

应用二:
从普通用户切换到root之后,执行“ls”操作,调用执行aaa.sh,返回执行结果,间隔10S。
#/usr/bin/expect    -f
spawn  su  -                        //  在expect 中用"spawn"关键字来调用命令“su - ”
expect  ":"                           //在执行了su   -  命令之后,提示输入密码的提示符。例如你在执行了su - 命令之后,终端里面会出现提示“口令:”,那么你就可以在这里写expect    ":",或者expect    -exact    "口令:"
send    "rootpasswd\r"      //这里expect用send将你的root密码自动输入到上面的提示符之后。
expect   "#"                      //当遇到提示符以#结尾时,即为root权限时;
send      "ls\r"                 //expect  用spend方法调用ls 命令,并且回车(“\r”)
expect   "#"
send   "sh  aaa.sh\r"         //调用sh aaa.sh,即执行一个脚本文件aaa.sh。
expect    "#"
send   "echo  $?\r"
sleep 10
interact


原文地址:http://www.blogjava.net/jasmine214--love/archive/2010/12/28/341794.html






重新签名(Re-sign)IPA

预备

了解Certificates、Identifiers、Devices和Provisioning Profiles之间的相互联系。

需求

1、在开发中,有时候版本迭代相当的快,比如每半个小时通过脚本自动做一个IPA,当有一台新设备要安装昨天某个时候的IPA时,就需要用新的Certificate和Provisioning Profile来重新签名;
2、一个$99的开发帐号,最多可以注册100台设备,也就是你的App在上架之前,最多只有100台设备可以安装,如果用多个开发帐号re-sign的话,就没有这个限制了。

准备

1、Certificate文件(后缀.p12);
2、Provisioning Profile文件(后缀.mobileprovision);
3、Xcode需要安装“Command Line Tools”。

实践

1、双击.p12文件,确保将其加入到钥匙串(Keychain Access);
2、获取钥匙串中证书的名称;
3、编写如下的脚本

#!/bin/sh

#获取第一个参数,也就是要用于重新签名的IPA名称,带后缀.ipa
OLD_IPA=$1
#获取第二个参数,也就是重新签名之后的IPA名称,不带后缀
NEW_IPA=$2

#所用的Provisioning Profile文件
RESIGN_PROVISION="cdz_dev.mobileprovision"
#所用的证书名称
RESIGN_CERT="iPhone Developer: DAOZHENG CHEN (PAFZRFHS4R)"
#你的IPA解压之后,在Payload文件里面的那个文件夹名称后缀是.app
APPNAME="fivechess"
#解压IPA,并记录log
unzip $OLD_IPA > resign.log
#删除原来的签名和mobileprovision文件
rm -r "Payload/$APPNAME.app/_CodeSignature"
rm -r "Payload/$APPNAME.app/embedded.mobileprovision"

#拷贝新的profile文件
cp "$RESIGN_PROVISION" "Payload/$APPNAME.app/embedded.mobileprovision"

#重新签名
/usr/bin/codesign -f -s "$RESIGN_CERT" --resource-rules "Payload/$APPNAME.app/ResourceRules.plist" "Payload/$APPNAME.app"

echo "$RESIGN_CERT"

#压缩IPA
zip -qr "$NEW_IPA.ipa" Payload

rm -r "Payload"

4、在Mac OS下,运行上面的脚本。
运行格式:./脚本名称   待重新签名的IPA名称(带后缀)   重新签名之后的IPA名称(不带后缀)

总结

1、如果碰到脚本没有可执行权限的话,用chmod   777   脚本名;
2、如果碰到权限问题的话,在运行格式前面加sudo。

参考

http://stackoverflow.com/questions/5160863/how-to-re-sign-the-ipa-file
https://developer.apple.com/library/mac/documentation

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小蓝xlanll/article/detail/612880
推荐阅读
相关标签
  

闽ICP备14008679号