四处集成与不断分发,自动打包ipa并导出

  • xcodebuild主要是用来编译,打包成Archive和导出ipa包。
  • 官方文档 Workspace、Project、Scheme、Target的区别
  • altool提交到App Store使用
  • altool使用官方文档第38页
  • altool 这个工具实际上是ApplicationLoader,打开Xcode-左上角Xcode-Open Developer Tool-Application Loader
  • altool的路径是:

本文始发于我的博文详解Shell脚本实现iOS自动化编译打包提交,现转发至此。

自动打包

摘要

手动打包、手动上传是一件非常烦琐的事件,通常会浪费开发者大量的时间,这时候自动打包与分发就起到的重要的角色。本文主要分为4个部分

  • 讲述jenkins在mac下的安装与任务创建
  • fastlane安装与应用
  • 自动上传到蒲公英并邮件通知相关人员去下载安装
  • xcode打包原理

  • 前言
  • Shell脚本涉及的工具
    • xcodebuild和xcrun
    • altool
    • fir-cli
    • PlistBuddy
  • 一些概念的区别
  • 具体实现
    • xcodebuild和xcrun
    • 准备Plist文件
    • 获取命令行参数
    • 清理构建目录
    • 编译打包成Archive
    • 将Archive导出
    • 上传到Fir
    • 验证并上传到App Store
    • 邮件通知相关同事
    • 上传符号表到Bugly
  • 简单例子
  • 对比实验
    • 三种方式的对比
    • xcodebuild xcrun和仅xcodebuild的比较
    • 命令到底做了什么
  • 总结

网上已经有许多开发者共享的打包脚本,只要输入一个命令就可以自动打包、发布、邮件通知。 

一、mac环境下jenkins的安装与配置

/Applications/Xcode.app/Contents/Applications/Application Loader.app/Contents/Frameworks/ITunesSoftwareService.framework/Support/altool

现在涉及到编译打包的工作主要是以下两个:

但是最近发现,一个简单的方法,可以让我们变得更懒一些。 

1.1 手动下载安装
  • 下载地址: https://jenkins.io/,安装与我们平时安装别的软件差不多
  • 使用时如报如下错误
  1. 提交测试版本给测试同事
  2. 提交App Store审核

图片 1

1.2 通过终端安装
  • 安装 homebrew
    ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
  • 安装 jenkins
    brew install jenkins

    jenkins-1.png

  • 查看jenkins目录:cd /Users/用户名/.jenkins

    jenkins11.png

两个流程分别是:

预备知识

1.3 启动jenkins与配置
  • 在终端输入:jenkins即可后台启动服务,然后用浏览器启动页面如下:
  • 直接在命令行中输入:jenkins即可启动。下面三个为常用的jenkins启停方法
    http://localhost:8080 // 打开jenkins可视化页面
    http://localhost:8080/exit //退出Jenkins
    http://localhost:8080/restart //重启
    http://localhost:8080/reload //重新加载
  • 启动时,需要解锁jenkins,按照提示去目录下打开文件,把密码复制出来填入输入框,如果碰到权限问题,需要进行操作: 右键 - 显示简介 - 修改权限。
jenkins-3.png
  • 启动后,选择安装推荐插件等,即下图中的第一项
jenkins-4.png
  • 设置管理员信息
jenkins2.png
  • 进入主面,如下
jenkins3.png
altool[] *** Error: Exception while launching iTunesTransporter: Transporter not found at path: /usr/local/itms/bin/iTMSTransporter. You should reinstall the application.
  • 修改证书和配置文件,然后「Product -> Archive」编译打包,之后在自动弹出的 「Organizer」 中进行选择,根据需要导出 ad hoc enterprise 类型的 ipa 包。等待导出之后再提交到Fir上,等Fir提交完成就需要告知测试同事。整个流程下来一般都要半个多小时,而且需要人工监守操作。
  • 第二个也是差不多,打包完之后需要操作几个步骤然后上传到App Store,上传时间较长,而且中间可能会有错误需要处理。上传后等待苹果处理二进制包,苹果处理后上去选择构建包,点击提交审核。

这里不会专门讲解以下知识(因为你不需要这些知识也可以使用本文提供的工具),请自行了解 

1.34 jenkins钥匙串插件,访问地址与端口号更改等

  • 地址修改
    进入上面中系统管理->系统设置
    如下:
jenkins-5.png
  • 全局属性设置

    jenkins5.png

上图中,PATH参数获取方法:  
终端输入`echo $PATH`  

jenkins-8.png
  • 打包成功或失败,邮件通知
![Uploading jenkins-6_671804.png . . .]



jenkins-6.png
  • 建立软链

所以研究下自动化编译打包,提高下效率,减少人工操作成本。

  1. 使用 automator Automator for Mac OS X: Tutorial and Examples 

  2. 使用 shell script Shell脚本编程30分钟入门 

  3. 使用 applescript Introduction to AppleScript Language Guide 

  4. xcodebuild xcodebuild 手册 

  5. Application Loader altool altool 手册

1.4 jenkins插件安装

上面我们选择推荐安装,对于ios开发,其实大部分已经默认安装,这里我们以keychain为例安装一个(后续fastlane用到match匹配同步开发证书时,会访问钥匙串)

  • 在jenkins主面,系统管理->控件管理
jenkins11.png
  • 选择可选插件,右边搜索框输入keychain,勾先安装完成后重启jenkins,点击安装
jenkins10.png
  • 设置keychain相关,在jenkins主面,系统管理->控件管理,点击keychain。。。,然后来点页面:

    jenkins12.png

打开keychain位置的命令:`open ~/Library/Keychains/`  
如果不设置这个,那么在创建任务中,在Excute
shell中就要加上这句:`security unlock-keychain -p 你的电脑密码 login.keychain`

主要有两种实现途径,AppleScript和Shell脚本,AppleScript没怎么研究,网上说是很强大的脚本语言。

使用xcodebuild打包

1.5 jenkins任务创建与任务配置
  • 创建,新建->选择构建一个自由风格的软件项目。如下图
jenkins7.png



然后主面右边就会出现刚创建好的。点击进去。来到任务主页。
  • 任务主页
jenkins13.png
  • 配置相关信息

    • 配置构建存留周期次数、Git等,如下图
    jenkins14.png

-   配置运行脚本,这里主要配置一些你打包的命令脚本。  

    jenkins15.png


    这里的脚本,可以参照下文**第二部分**fastlane中fastfile配置,里面实现了fastlane
    matchDev与fastlane dev操作。

-   定期自动构建  

    jenkins18.png


    **常用的poll scm设置**  
    `每15分钟构建一次:H/15 * * * * 或*/5 * * * *`  
    `每天8点构建一次:0 8 * * *`  
    `每天8点~17点,两小时构建一次:0 8-17/2 * * *`  
    `周一到周五,8点~17点,两小时构建一次:0 8-17/2 * * 1-5`  
    `每月1号、15号各构建一次,除12月:H H 1,15 1-11 *`

-   构建后操作,邮件通知等



    jenkins16.png



    操作步骤: 增加构建后操作->Editable Email
    Notification,然后点击下面的Advanced
    Settings,就会出现上面的图,填写好标题两天内容即可。

-   邮件发送成功示例



    jenkins17.png

-   构建过程中,可通过点击当前构建,点击console
    output查看打包过程中的输出日志。



    jenkins20.png

建议把jenkins页面右上角的允许自动刷新打开


ln -s /Applications/Xcode.app/Contents/Applications/Application Loader.app/Contents/itms /usr/local/itms

下面主要讲Shell脚本的实现,网上也有人实现了并托管在github上,可以参考下。

xcodebuild 

二、fastlane安装与配置

fastlane是一个完全开源的项目,包含一组 Ruby 实现的工具集,能完成 iOS 和 Android 工程 的自动化构建测试和发布,用来执行某一特定的任务,可以通过配置文件将不同的工具灵活的结合在一起,从而形成一个完整的自动化流程,实现一键上传 ITC,从而缩短用于构建发布的时间,其主要工具集如下:

  • sigh: 开发证书和描述文件下载
  • produce: 使用命令行在iTunes Connect上创建新的app和开发入口
  • cert: 自动创建和配置iOS代码签名证书
  • spaceship: Ruby 库访问 Apple开发者中心和 iTunes Connect
  • pilot: 最好的方式管理你的TestFlight 测试人员和从终端构建
  • boarding: 最简单的方式邀请你的TestFlight beta测试人员
  • gym: iOS app打包签名自动化工具
  • match: 使用Git同步你的团队证书和配置文件
  • scan: 最简单方式测试你的 iOS 和 Mac apps

查看所有的工具集:fastlane actions
单独查看某一个action的功能: fastlane action [action_name]

  • 如果想要在脚本中修改plist文件的内容可以使用PlistBuddy,PlistBuddy是Mac里一个用于命令行下读写plist文件的工具,在/usr/libexec/下。可以通过它读取或修改plist文件的内容。

打包、导出ipa都是使用的 xcodebuild 

2.1 fastlane的安装
  • 检查xcode-select 是安装
xcode-select --install // 若未安装则会自动安装,若已经安装,则提示:xcode-select: error: command line tools are already installed, use "Software Update" to install updates
  • 安装fastlane
sudo gem install -n /usr/local/bin fastlane
  • 查看版本
fastlane --version

主要是以下几个工具:

可能你的工程需要指定 target,或者需要其他参数才能打出正确的包,了解一下xcodebuild还是很有必要的 

2.2 为项目配置的fastlane
  • 在工程目录在,用终端初始化
cd 工程目录
fastlane init 
  • init过程,由于我的帐号关联了两个开发者帐号,于是会弹出让我选择哪一个的选项。
fastlane1.png

上述过程中,会要求你填写开发者帐号密码等信息。完成后,会在你的工程目录在创建一个fastlane文件夹

  • 文件夹如图所示
fastlane2.png



各文件描述:

-   Appfile:用于存储应用程序标识符和Apple ID 等信息
-   Fastfile:配置管理 lane `我们打包主要是配置这个文件`
-   Deliverfile:配置应用在 iTunes Connect 中的各种信息,和 ICC
    中的数据是一一对应的
-   metadata:包含应用在 iTunes Connect 中的各种信息
-   screenshots:包含截图数据

项目工程中,Edit Scheme打开的页面,Shared前的勾选框,应该打上勾。不然jenkins打包过程中,可能报错。
接下来主要讲述Fastfile文件配置

#!/bin/sh# PlistBuddy程序的绝对路径PlistBuddyPath=/usr/libexec/PlistBuddyappInfoPlistPath="/Volumes/SourceCode/showstart_ios/ShowStart_3.0/Info.plist"bundleShortVersion=$($PlistBuddyPath -c "print CFBundleShortVersionString" ${appInfoPlistPath})bundleVersion=$($PlistBuddyPath -c "print CFBundleVersion" ${appInfoPlistPath})echo "$bundleShortVersion"echo "$bundleVersion"buildNumber="3.69"bundleVersion=$($PlistBuddyPath -c "Set :CFBundleVersion $buildNumber" ${appInfoPlistPath})bundleVersion=$($PlistBuddyPath -c "print CFBundleVersion" ${appInfoPlistPath})echo "$bundleVersion"
  1. xcodebuild
  2. xcrun
  3. altool(提交到App Store使用)
  4. fir-cli(上传到fir时使用)
  5. Python的smtplib(之前已经写过python的发邮件了,所以就直接用没有用Shell写。)
  6. PlistBuddy
  7. BuglySymboliOS(Bugly的符号表工具包)

代码中用到的exportOptionsPlist是一个plis配置文件,稍后可以下载到

2.3 fastfile文件编写

下面用到的工具match、gym、deliver、gpyer等,均可以通过:fastlane 工具名 --help查看里面的参数如何写等

  • match匹配证书
    • 首先要一个仓库来存放证书与profile文件
    fastaneMatch1.png

-   在工程目录下执行
    `fastlane match init`,过程中会要求你填入一个git仓库。把上面创建好的填入即可。  

    fastaneMatch2.png

-   这样,在fastlane文件夹会添加一个Matchfile文件。



    fastaneMatch3.png

-   内容如下



    fastaneMatch4.png

-   在fastfile文件中,添加匹配证书的执行块:  

    fastaneMatch6.png


    其中,match函数中的参数key与参数值value,可在终端执行:`fastlane match --help`
    或者
    github上查看:[match](https://link.jianshu.com?t=https://github.com/fastlane/fastlane/tree/master/match)
-   在终端执行`fastlane matchDev`后,仓库上,keychain中,jenkins环境中,均会有证书相关文件  

    fastaneMatch5.png


    **执行fastlane
    matchDev,途中会要求访问钥匙串,要输入电脑密码。如果把这脚本写到jenkins
    Excute
    shell中,那么会碰到超时,提示未输入username,于是我们会在shell中添加:`security unlock-keychain -p 你的电脑密码 login.keychain`或者在插件管理中,把login.keychain先配置好**

<!-- -->

-   registerDevice 添加新设备UUID
desc "添加新设备UUID"
desc "This will also make sure the profile is up to date"
lane :registerDev do
    register_device(
      name: "名字",
      udid: "227a4********1349e27***c211e**69")
end
--------------这样,在匹配证书时,就要用到:force_for_new_devices属性---------------
desc "匹配生成证书"
desc "This will also make sure the profile is up to date"
lane :matchAppstore do
    match(type: "appstore",keychain_password: ENV['PASSWORD'],force_for_new_devices:true) # 匹配开发证书
end
  • gym打包

    • 在fastfile中配置打包,这里用到gym工具,可通过fastlane gym --help或github查看gym用法

      fastaneMatch7.png

    其中,首先匹配证书。像里面用到的increment_build_number
    这些都可通过fastlane actions查看到。  
    下面这样,省去build版本自增等,更为简洁。
desc "打包测试"
  lane :dev do
    match(git_url:"https://git.oschina.net/yang***/cer.git",type: "development",keychain_password:"123",app_identifier:"cn.com.**") # 匹配开发证书

     # 打包,具体参数可fastlane gym -h查看
     gym(clean: true,scheme:"GC",configuration:"Debug",output_name:"GC_Test",export_method:"development")

    # 上传到薄公英,可以去薄公英官网查看插件安装方法
     pgyer(api_key: "6ef35de7a3c4c60***dd48825eac3a", user_key: "ce1e4c***c27232fcde878db3",password: "a**23", install_type: "2")
    # 发布
     # deliver(force: true,skip_screenshots:true,skip_metadata: true)    # 不上传截屏文件和元数据。
  end

上面有用到上传蒲公英,接下来第三部分讲述pgyer的用法。


  • 百度了一下大多数文章使用xcodeuildxcrun编译导出ipa

xcodebuild和xcrun

xcodebuildxcrun都是来自Command Line Tools,Xcode自带,如果没有可以通过以下命令安装:

xcode-select --install

或者在下面的链接下载安装:

安装完可在以下路径看到这两个工具:

/Applications/Xcode.app/Contents/Developer/usr/bin/

  • xcodebuild主要是用来编译,打包成Archive和导出ipa包。

可以执行 xcodebuild -help 查看,主要展示了几种用法、一些可选项,最后是比较重要的exportOptionsPlist文件的一些可选key,这个文件在后面导出ipa包会用到。

主要下面三个查看的命令比较重要:

-showsdks display a compact list of the installed SDKs-showBuildSettings display a list of build settings and values-list lists the targets and configurations in a project, or the schemes in a workspace

后面两个需要在Xcode的project或者workspace目录下才能用。

  • xcrun
xcrun -h

主要是打包,看网上比较多是用这个工具打包各种渠道包。

#xcodebuild 简单示例

三、pgyer插件安装与配置

pgyer安装与使用官方文档:使用 Fastlane 上传 App 到蒲公英
在工程目录在,用终端键入:

fastlane add_plugin pgyer
  • 安装后,工程目录下会有Gemfile文件,fastlane文件下,会多出pluginfile文件
pgyer1.png
  • pluginfile如下
pgyer2.png
  • fastlane ,在fastlfile中配置上传蒲公英操作
lane :uploadPgyer do
  pgyer(api_key: "7f15xxxxxxxxxxxxxxxxxx141", user_key: "4a5bcxxxxxxxxxxxxxxx3a9e", password: "123456", install_type: "2")
end
  • 上面,api_key与user_key获取如下:
pgyer3.png

altool

这个工具在网上搜索几乎没有什么结果,大概国内直接用命令行工具提交App Store的比较少。后来在StackOverflow上才找到相关的文档:

在上面的文档第38页讲述了如何使用altool上传二进制文件。

这个工具实际上是ApplicationLoader,打开Xcode-左上角Xcode-Open Developer Tool-Application Loader 可看到。有个“交付您的应用”操作,网上看到有人是直接用这个工具上传的。

altool的路径是:

/Applications/Xcode.app/Contents/Applications/Application Loader.app/Contents/Frameworks/ITunesSoftwareService.framework/Support/altool

使用时会提示下面的错误:

altool[] *** Error: Exception while launching iTunesTransporter: Transporter not found at path: /usr/local/itms/bin/iTMSTransporter. You should reinstall the application.

建立个软链接可解决(类似于Windows的快捷方式):

ln -s /Applications/Xcode.app/Contents/Applications/Application Loader.app/Contents/itms /usr/local/itms

#build clean

四、xcode打包原理

xcode打包,用的就是xcodebuild命令完成的。可以通过man xcodebuild命令查看文档
此部分参考了两位同事的文章:xcodebuild自动打包,发布应用与xcodebuild 自动化构建

  • xcode打包发布流程
    • xcodebuild clean
    • archive
    • exportArchive导出文件
    • altool上传
  • archive打包
xcodebuild archive -workspace 项目名称.xcworkspace 
                       -scheme 项目名称 
                       -configuration 构建配置 
                       -archivePath archive包存储路径 
                       CODE_SIGN_IDENTITY=证书 
                       PROVISIONING_PROFILE=描述文件UUID
  • configuration构建配置,可参考以前写的文章:Xcode通过Build Configuration配置多套域名方法,一般情况下,我们这里打测试包写:Debug,生产包:Release.
  • CODE_SIGN_IDENTITY获取:
    钥匙串访问->选中证书->上方的标题就是我们需要的Identity(括号也算),如:iPhone Developer: ** *** (WS4F**K**)
  • PROVISIONING_PROFILE:这个获取方法如下:
/Users/用户名/Library/MobileDevice/Provisioning Profiles 
找到对应的provisioning Profiles
如果文件较多,可在命令终端输入
security cms -D -i xxxx.mobileprovision // 解析描述文件,可以得到里面所有的信息(TeamId,ProvisionedDevices,TeamName,UUID,Version,AppIDName等等)。以确定哪一个是此项目所用到的

注意要 在CODE_SIGN_IDENTITY,PROVISIONING_PROFILE赋值时要加""号

  • 导出ipa包
xcodebuild -exportArchive -archivePath archive文件的地址.xcarchive 
                          -exportPath 导出的文件夹地址 
                          -exportOptionsPlist exprotOptionsPlist.plist 
                          CODE_SIGN_IDENTITY=证书 
                          PROVISIONING_PROFILE=描述文件UUID
  • archive文件的地址.xcarchive
    这个地址为打包后,生成**.xcarchive文件的地址。
  • exportOptionsPlist
    这是一个plist文件,我们可以在项目中手动创建一个,然后把这个文件地址拖进来。plist具体有哪些参数,用命令:xcodebuild exportOptionsPlist --help查看,在输出的Available keys for -exportOptionsPlist项:

    jenkins12.png

  • ipa包上传,我们工作中一般用的是Application Loader或xcode 打包后的upload按钮,但是它们的本质其实都是用:altool来实现。
    altool工具的位置:

/Applications/Xcode.app/Contents/Applications/Application Loader.app/Contents/Frameworks/ITunesSoftwareService.framework/Versions/A/Support/altool

命令设置别名:

在~/.bash_profile 中设置别名
alias altool='/Applications/Xcode.app/Contents/Applications/Application Loader.app/Contents/Frameworks/ITunesSoftwareService.framework/Versions/A/Support/altool'

设置别名后在终端
输入 source ~/.bash_profile 以使其生效。
再输入 altool  就会有它的一些用法提示,否则就是设置别名失败了

同理,别的工具也可以用此方法实现别名处理,以快速在终端打开工具。

altool 用法:

验证 ipa
altool --validate-app -f file -u username [-p password] [--output- format xml]
上传 ipa
altool --upload-app -f file -u username [-p password] [--output- format xml]

具体参数说明:
--validate-app
您要验证的应用程序。
--upload-app
您要上传的应用程序。
-f file
您正在验证或上传的应用程序的路径和文件名。
-u username
您的用户名。
-p password
您的用户密码。
--output-format [xml | normal]
您要 Application Loader 以结构化的 XML 格式还是非结构化的文本格式返回输出信息。Application Loader 默认以文本格式返回输出信息。

altool官方文档

xcodebuild -workspace XXX -scheme XXX -configuration Releasexcrun -sdk iphoneos PackageApplication -v "/XXX/XXX.app" -o "/XXX/XXX"

fir-cli

安装时会提示各种权限不允许,可以执行下面命令:

echo 'gem: --bindir /usr/local/bin' >> ~/.gemrcsudo 'gem install fir-cli

fir有提供Android Studio、Eclipse、gradle插件,可以看下。

这是�它的github地址,其中讲到有对?xcodebuild?原生指令进行了封装。

xcodebuild  clean -configuration "$configuration" -alltargets

  • 另一种是xcodebuildarchive-exportArchive,然而最新需要使用--exportOptionsPlist选项,而不再使用--exportFromat
  • 使用xcodebuild -help命令可查看--exportOptionsPlist选项具体描述

PlistBuddy

Plist在Mac OSX系统中起着举足轻重的作用,系统和程序使用Plist文件来存储自己的安装/配置/属性等信息。而PlistBuddy是Mac里一个用于命令行下读写plist文件的工具,在/usr/libexec/下。可以通过它读取或修改plist文件的内容。

这里我仅通过它来获取内部版本号、外部版本号。在一些文章中见过用来修改plist文件的信息来导出出不同需要的包。

Workspace、Project、Scheme、Target的区别。

下面是官方文档:

下面从上往下大概说下,具体看文档比较好:

  • WorkspaceWorkspace是最大的集合,可以包含多个Project,可以管理不同的Project之间的关系。Workspace是以xcworkspace的文件形式存在的。(这点和Project一致)。Workspace的存在是为了解决原来仅有Project的时候不同的Project之间的引用和调用困难的问题。同时,一个WorkspaceProject共用一个编译路径。比如使用CocoaPod、或者使用其他开发库/框架。

  • ProjectProject是一个仓库,包含编译一个或多个product所需的文件、资源和信息,保持和聚合这些元素间的关系。(每个Target能指定自己的Build Settings来覆盖Project的)

  • Source code, including header files and implementation files
  • Libraries and frameworks, internal and external
  • Resource files
  • Image files
  • Interface Builder files
  • SchemeScheme包含了一些要构建的Scheme,一些构建时用到的设置,一些要运行的测试。同时只能有一个Scheme是有效的。

  • TargetTarget是对应了具体一个想要构建的Product,包含了一些构建这个Product所需的配置和文件(build settingsbuild phases)。一个Project可以包含多个Target

看起来有两种实现方法:

  • 网上可以查到的文章,大多数都是用xcodebuildxcrun实现的,比如:
xcodebuild -workspace XXX -scheme XXX -configuration Releasexcrun -sdk iphoneos PackageApplication -v "/XXX/XXX.app" -o "/XXX/XXX"

这些文章都是相对比早期的,大多数用于打包不同渠道包。

  • 另一种是xcodebuildarchive-exportArchive,只有一两篇文章是用这个,而且也过时了,因为现在最新是需要用-exportOptionsPlist这个选项。

我用的是第二种,并用上-exportOptionsPlist选项,后面我会简单给下这两种的结果比较。脚本流程是:

  1. 准备两个Plist文件,用于导出不同ipa包时使用。
  2. 获取命令行参数,区分上传到Fir还是App Store
  3. 清理构建目录
  4. 编译打包
  5. 导出包
  6. 上传到Fir或者验证并上传到App Store
  7. 发邮件通知

#archive

如何获取工程的CODE_SIGN_IDENTITYPROVISIONING_PROFILE

  • 右键 xxx.xcodeproj 显示包内容 然后打开project.pbxproj文件
  • command F 搜索 CODE_SIGN_IDENTITY PROVISIONING_PROFILE

图片 2QQ20161106-0.png图片 3QQ20161106-1.png

  • PROVISIONING_PROFILE 使用uuid或者名称都可以

  • 注意 因为我这里打包用的Release模式所以,我在查找CODE_SIGN_IDENTITYPROVISIONING_PROFILE都是找的Release模式配置

  • 使用atool时 最终输出的xml 中包含 success-message表示成功,如果包含product-errors表示失败

  • 执行脚本

// 首先把两个plist和脚本放到工程根目录,然后打开terminal进入项目// 第一次需要设置脚本的执行权限chmod  x xcodebuild.sh// 执行脚本./xcodebuild.sh

完整的脚本 其中 xxxx 替换为你自己的

#!/bin/shecho "~~~~~~~~~~~~~~~~开始执行脚本~~~~~~~~~~~~~~~~"# 开始时间beginTime=`date  %s`DATE=`date ' %Y-%m-%d-%T'`#需要编译的 targetNameTARGET_NAME="xxxx"#编译模式 工程默认有 Debug Release CONFIGURATION_TARGET=Release#编译路径BUILDPATH=~/Desktop/${TARGET_NAME}_${DATE}#archivePathARCHIVEPATH=${BUILDPATH}/${TARGET_NAME}.xcarchive#输出的ipa目录IPAPATH=${BUILDPATH}#证书名CODE_SIGN_IDENTITY="xxxxx"#描述文件PROVISIONING_PROFILE_NAME="xxxx"#苹果账号AppleID="xxxx"AppleIDPWD="xxxx"#导出ipa 所需plistADHOCExportOptionsPlist=./ADHOCExportOptionsPlist.plistAppStoreExportOptionsPlist=./AppStoreExportOptionsPlist.plistExportOptionsPlist=${ADHOCExportOptionsPlist}# 是否上传蒲公英UPLOADPGYER=false# 是否上传AppStoreUPLOADAPPSTore=falseecho "~~~~~~~~~~~~~~~~选择打包方式~~~~~~~~~~~~~~~~"echo " 1 ad-hoc "echo " 2 AppStore "# 读取用户输入并存到变量里read parametersleep 0.5method="$parameter"# 判读用户是否有输入 if [ -n "$method" ]then if [ "$method" = "1" ] then PROVISIONING_PROFILE_NAME="xxxx" ExportOptionsPlist=${ADHOCExportOptionsPlist} elif [ "$method" = "2" ] then UPLOADAPPSTore=true PROVISIONING_PROFILE_NAME="xxxx" ExportOptionsPlist=${AppStoreExportOptionsPlist} else echo "参数无效...." exit 1 fielse ExportOptionsPlist=${ADHOCExportOptionsPlist}fiif [ $UPLOADAPPSTore = false ]then echo "~~~~~~~~~~~~~~~~是否上传蒲公英~~~~~~~~~~~~~~~~" echo " 1 不上传 " echo " 2 上传 " read para sleep 0.5 if [ -n "$para" ] then if [ "$para" = "1" ] then UPLOADPGYER=false elif [ "$para" = "2" ] then UPLOADPGYER=true else echo "参数无效...." exit 1 fi else UPLOADPGYER=false fifiecho "~~~~~~~~~~~~~~~~开始编译~~~~~~~~~~~~~~~~~~~"echo "~~~~~~~~~~~~~~~~开始清理~~~~~~~~~~~~~~~~~~~"# 清理 避免出现一些莫名的错误xcodebuild clean -workspace ${TARGET_NAME}.xcworkspace -configuration ${CONFIGURATION} -alltargetsecho "~~~~~~~~~~~~~~~~开始构建~~~~~~~~~~~~~~~~~~~"#开始构建xcodebuild archive -workspace ${TARGET_NAME}.xcworkspace -scheme ${TARGET_NAME} -archivePath ${ARCHIVEPATH} -configuration ${CONFIGURATION_TARGET} CODE_SIGN_IDENTITY="${CODE_SIGN_IDENTITY}" PROVISIONING_PROFILE="${PROVISIONING_PROFILE_NAME}"echo "~~~~~~~~~~~~~~~~检查是否构建成功~~~~~~~~~~~~~~~~~~~"# xcarchive 实际是一个文件夹不是一个文件所以使用 -d 判断if [ -d "$ARCHIVEPATH" ]thenecho "构建成功......"elseecho "构建失败......"rm -rf $BUILDPATHexit 1fiendTime=`date  %s`ArchiveTime="构建时间$[ endTime - beginTime ]秒"echo "~~~~~~~~~~~~~~~~导出ipa~~~~~~~~~~~~~~~~~~~"beginTime=`date  %s`xcodebuild -exportArchive -archivePath ${ARCHIVEPATH} -exportOptionsPlist ${ExportOptionsPlist} -exportPath ${IPAPATH}echo "~~~~~~~~~~~~~~~~检查是否成功导出ipa~~~~~~~~~~~~~~~~~~~"IPAPATH=${IPAPATH}/${TARGET_NAME}.ipaif [ -f "$IPAPATH" ]thenecho "导出ipa成功......"elseecho "导出ipa失败......"# 结束时间endTime=`date  %s`echo "$ArchiveTime"echo "导出ipa时间$[ endTime - beginTime ]秒"exit 1fiendTime=`date  %s`ExportTime="导出ipa时间$[ endTime - beginTime ]秒"# 上传AppStoreif [ $UPLOADAPPSTore = true ]then altoolPath="/Applications/Xcode.app/Contents/Applications/Application Loader.app/Contents/Frameworks/ITunesSoftwareService.framework/Versions/A/Support/altool" ${altoolPath} --validate-app  -f ${IPAPATH}  -u ${AppleID}  -p ${AppleIDPWD}  -t ios --output-format xml if [ $? = 0 ] then echo "~~~~~~~~~~~~~~~~验证ipa成功~~~~~~~~~~~~~~~~~~~" ${altoolPath} --upload-app  -f ${IPAPATH}  -u ${AppleID}  -p ${AppleIDPWD}  -t ios --output-format xml if [ $? = 0 ] then echo "~~~~~~~~~~~~~~~~提交AppStore成功~~~~~~~~~~~~~~~~~~~" else echo "~~~~~~~~~~~~~~~~提交AppStore失败~~~~~~~~~~~~~~~~~~~" fi else echo "~~~~~~~~~~~~~~~~验证ipa失败~~~~~~~~~~~~~~~~~~~" fielse # 上传蒲公英 if [ $UPLOADPGYER = true ] then echo "~~~~~~~~~~~~~~~~上传ipa到蒲公英~~~~~~~~~~~~~~~~~~~" curl -F "file=@$IPAPATH"  -F "uKey=xxxxx"  -F "_api_key=xxxx"  -F "password=xxxxx"  -F "isPublishToPublic=xxxx"  https://www.pgyer.com/apiv1/app/upload --verbose if [ $? = 0 ] then echo "~~~~~~~~~~~~~~~~上传蒲公英成功~~~~~~~~~~~~~~~~~~~" else echo "~~~~~~~~~~~~~~~~上传蒲公英失败~~~~~~~~~~~~~~~~~~~" fi fifiecho "~~~~~~~~~~~~~~~~配置信息~~~~~~~~~~~~~~~~~~~"echo "开始执行脚本时间: ${DATE}"echo "编译模式: ${CONFIGURATION_TARGET}"echo "导出ipa配置: ${ExportOptionsPlist}"echo "打包文件路径: ${ARCHIVEPATH}"echo "导出ipa路径: ${IPAPATH}"echo "$ArchiveTime"echo "$ExportTime"exit 1

github

准备Plist文件

根据xcodebuild -help提供的可选key可以知道,compileBitcodeembedOnDemandResourcesAssetPacksInBundleiCloudContainerEnvironmentmanifestonDemandResourcesAssetPacksBaseURLthinning这几个key用于非App Store导出的;uploadBitcodeuploadSymbols用于App Store导出;methodteamID共用。

method的可选值为:

app-store, package, ad-hoc, enterprise, development, and developer-id

所以我建了两个文件:AppStoreExportOptions.plistAdHocExportOptions.plist

AppStoreExportOptions.plist:method=app-store,uploadBitcode=YES,uploadSymbols=YES

AdHocExportOptions.plist:method=ad-hoc,compileBitcode=NO

xcodebuild  archive  -workspace "$workspaceName" -scheme "$scheme" -configuration  "$configuration"  -archivePath ${archivePath}/${archiveName}.xcarchive  CODE_SIGN_IDENTITY="$codeSignIdentity"  PROVISIONING_PROFILE="$appStoreProvisioningProfile"

获取命令行参数

Shell内置的getopts命令,这属于Shell的范畴就不多讲了:

if [ $# -lt 1 ];then echo "Error! Should enter the archive type (AdHoc or AppStore)." echo "" exit 2fiwhile getopts 't:' optnamedo case "$optname" in t) if [ ${OPTARG} != "AdHoc" ] && [ ${OPTARG} != "AppStore" ];then echo "invalid parameter of $OPTARG" echo "" exit 1 fi type=${OPTARG} ;; *) echo "Error! Unknown error while processing options" echo "" exit 2 ;; esacdone

#导出到ipa

清理构建目录

就如在Xcode操作「Product -> Clean」。

log_path="/XXX/XXX"configuration="Release"xcodebuild clean -configuration "$configuration" -alltargets >> $log_path

log_path是一个文档路径,只是用来记录命令的输出,因为都打在终端会很多,另外也方便后面分析。后面的命令也是如此。这里面带的选项可以根据需要参考xcodebuild -help的信息。

xcodebuild -exportArchive -archivePath ${archivePath}/${archiveName}.xcarchive -exportOptionsPlist "$exportOptionsPlist" -exportPath ${archivePath}/${archiveName}

编译打包成Archive

就如在Xcode操作「Product -> Archive」

workspaceName="XXX.xcworkspace"scheme="XXX"configurationBuildDir="XXX/build"codeSignIdentity="iPhone Distribution: XXX, Ltd. (xxxxxxxxxx)"adHocProvisioningProfile="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"appStoreProvisioningProfile="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"configuration="Release"archivePath="/xxx/XXX.xcarchive"xcodebuild archive -workspace "$workspaceName" -scheme "$scheme" -configuration "$configuration" -archivePath "$archivePath" CONFIGURATION_BUILD_DIR="$configurationBuildDir" CODE_SIGN_IDENTITY="$codeSignIdentity" PROVISIONING_PROFILE="$provisioningProfile" >> $log_path

这里的CONFIGURATION_BUILD_DIR是中间文件生成的路径,可以不指定;CODE_SIGN_IDENTITY是证书名(在对应TARGETSBuild Settings中选择完Code Sinning,再点击选择Other...,就可以得到这串东西);PROVISIONING_PROFILE是配置文件(获取方法同CODE_SIGN_IDENTITY,格式一般是xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx)。还可以添加其他参数,不设置的都是默认使用项目Build Settings里面的配置,包括CODE_SIGN_IDENTITYPROVISIONING_PROFILE

如果是workspace就用-workspace,就像编译带有CocoaPods的项目,如果是普通项目则用-project

执行完会生成一个.xcarchive文件和build文件夹如下:

.xcarchivebuild文件夹 |------.a |------.app |------.app.dSYM |------.swiftmodule文件夹 |------arm.swiftdoc |------arm.swiftmodule |------arm64.swiftdoc |------arm64.swiftmodule

使用altool提交ipa

将Archive导出

xcodebuild -exportArchive -archivePath "$archivePath" -exportOptionsPlist "$exportOptionsPlist" -exportPath "/XXX/XXX" >> $log_path

其中$exportOptionsPlist是对应使用的Plist的完整路径。

然后就会在指定的exportPath路径下生成.ipa文件。

Application Loader altool 

上传到Fir

firApiToken="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"ipaPath="/xxx/xxx.ipa"fir publish "$ipaPath" -T "$firApiToken" >> $log_path

firApiToken在登录Fir后,右上角-API token看到。

altool 位于 Application Loader,三个参数 ipapath、appleid、password 

验证并上传到App Store

altoolPath="/Applications/Xcode.app/Contents/Applications/Application Loader.app/Contents/Frameworks/ITunesSoftwareService.framework/Versions/A/Support/altool"${altoolPath} --validate-app -f ${ipaPath} -u xxxxxx -p xxxxxx -t ios --output-format xml >>${altoolPath} --upload-app -f ${ipaPath} -u xxxxxx -p xxxxxx -t ios --output-format xml

在上面的PDF文档第38页讲明了用法和各个可选项,具体可以看下PDF。需要说明的是,生成的结果是xml打印在终端,可以保存到文档再解析出key来判断是否成功,目前这步还没做。

这是成功的结果:

<?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>os-version</key> <string>10.11.2</string> <key>success-message</key> <string>No errors validating archive at /XXX/XXX.ipa</string> <key>tool-version</key> <string>1.1.902</string> <key>xcode-versions</key> <array> <dict> <key>path</key> <string>/Applications/Xcode.app</string> <key>version.plist</key> <dict> <key>BuildVersion</key> <string>7</string> <key>CFBundleShortVersionString</key> <string>7.2</string> <key>CFBundleVersion</key> <string>9548</string> <key>ProductBuildVersion</key> <string>7C68</string> <key>ProjectName</key> <string>IDEFrameworks</string> <key>SourceVersion</key> <string>9548000000000000</string> </dict> </dict> </array></dict></plist>

这是失败的结果(找不到iTMSTransporter的情况,用前面说的ln -s解决):

<?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>os-version</key> <string>10.11.2</string> <key>product-errors</key> <array> <dict> <key>code</key> <integer>-10001</integer> <key>message</key> <string>Transporter not found at path: /usr/local/itms/bin/iTMSTransporter. You should reinstall the application.</string> <key>userInfo</key> <dict> <key>MZUnderlyingException</key> <string>Transporter not found at path: /usr/local/itms/bin/iTMSTransporter. You should reinstall the application.</string> <key>NSLocalizedDescription</key> <string>Transporter not found at path: /usr/local/itms/bin/iTMSTransporter. You should reinstall the application.</string> <key>NSLocalizedFailureReason</key> <string>Transporter not found at path: /usr/local/itms/bin/iTMSTransporter. You should reinstall the application.</string> </dict> </dict> </array> <key>tool-version</key> <string>1.1.902</string> <key>xcode-versions</key> <array> <dict> <key>path</key> <string>/Applications/Xcode.app</string> <key>version.plist</key> <dict> <key>BuildVersion</key> <string>7</string> <key>CFBundleShortVersionString</key> <string>7.2</string> <key>CFBundleVersion</key> <string>9548</string> <key>ProductBuildVersion</key> <string>7C68</string> <key>ProjectName</key> <string>IDEFrameworks</string> <key>SourceVersion</key> <string>9548000000000000</string> </dict> </dict> </array></dict></plist>

可见,成功会有个success-message的key,而失败会有product-errors的key。

在这之前我都是使用的Application Loader上传包到 iTunesConnect

邮件通知相关同事

发邮件时可能会想带上当前版本的一些信息,如版本号、内部版本号等,可以用PlistBuddy实现读取甚至修改Plist文件。

appInfoPlistPath="`pwd`/xxx/xxx-Info.plist"bundleShortVersion=$(/usr/libexec/PlistBuddy -c "print CFBundleShortVersionString" ${appInfoPlistPath})bundleVersion=$(/usr/libexec/PlistBuddy -c "print CFBundleVersion" ${appInfoPlistPath})

之后便是发邮件:

python sendEmail.py "测试版本 iOS ${bundleShortVersion}(${bundleVersion})上传成功" "赶紧下载体验吧!http://fir.im/meijia"

或者

python sendEmail.py "正式版本 iOS ${bundleShortVersion}(${bundleVersion})提交成功" "iOS ${bundleShortVersion} 提交成功!"

python主要用smtplib,网上的文章大多都是旧的,特别是讲到SSL时特别复杂,其实具体看下smtplib的接口文档就可以实现了。另外有可能出现标题、内容乱码的现象。整合了下面的链接解决了:

下面是实现了SSL Smtp登录的。

#!/usr/bin/env python3#coding: utf-8# sendEmail title contentimport sysimport smtplibfrom email.mime.text import MIMETextfrom email.header import Headersender = 'xxxxxx@qq.com;'receiver = 'xxx@qq.com;'smtpserver = 'smtp.qq.com'#smtpserver = 'smtp.exmail.qq.com'username = senderpassword = 'xxxxxx'def send_mail(title, content): try: msg = MIMEText(content,'plain','utf-8') if not isinstance(title,unicode): title = unicode(title, 'utf-8') msg['Subject'] = title msg['From'] = sender msg['To'] = receiver msg["Accept-Language"]="zh-CN" msg["Accept-Charset"]="ISO-8859-1,utf-8" smtp = smtplib.SMTP_SSL(smtpserver,465) smtp.login(username, password) smtp.sendmail(sender, receiver, msg.as_string smtp.quit() return True except Exception, e: print str return Falseif send_mail(sys.argv[1], sys.argv[2]): print "done!"else: print "failed!"

可以赋值给msg['CC']实现抄送,经过测试,抄送的人过多会有一部分不成功,网上查了是这个库的bug。发送多个人用分号,另外末尾也要用分号。

#altool简单示例#validate"$altoolPath"--validate-app-f"$ipaPath"-u"$appleid"-p"$applepassword"-tios--output-formatxml#upload"$altoolPath"--upload-app-f"$ipaPath"-u"$appleid"-p"$applepassword"-tios--output-formatxml

上传符号表到Bugly

用于分析解决崩溃bug挺好用的,而且他们的客服也很及时。发现他们的2.4.1版本有问题,反馈后他们给了2.4.3版本,经测试没问题。

  1. 在Bugly官网下载符号表工具

  2. 设置settings.txt

  3. 调用命令

java -jar buglySymboliOS.jar -d -i $dSYM -u -id "xxxxxxxxx" -key "xxxxxxxxxxx" -package "com.xxx.xxx" -version "$version" ­-o "xxx.zip"

注意版本号之类的要设置对。

清理构建目录:

xcodebuild clean -configuration Release -alltargets

归档(其他参数不指定的话,默认用的是.xcworkspace或.xcodeproj文件里的配置)

xcodebuild archive -workspace xxx.xcworkspace -scheme xxx -configuration Release -archivePath ./xxx.xcarchive

导出IPA

xcodebuild -exportArchive -archivePath ./xxx.xcarchive -exportOptionsPlist ./AdHocExportOptions.plist -exportPath ./

上传FIR

fir publish ./xxx.ipa -T xxxxxx

提交AppStore

/Applications/Xcode.app/Contents/Applications/Application Loader.app/Contents/Frameworks/ITunesSoftwareService.framework/Versions/A/Support/altool --validate-app -f ./xxx.ipa -u xxx -p xxx -t ios --output-format xml/Applications/Xcode.app/Contents/Applications/Application Loader.app/Contents/Frameworks/ITunesSoftwareService.framework/Versions/A/Support/altool --upload-app -f ./xxx.ipa -u xxx -p xxx -t ios --output-format xml

发邮件

python sendEmail.py "邮件内容" "用户名" "密码"

上传符号表

java -jar buglySymboliOS.jar -d -i $dSYM -u -id "xxxxxxxxx" -key "xxxxxxxxxxx" -package "com.xxx.xxx" -version "$version" ­-o "xxx.zip"

为了了解一些区别,我做了几个对比。我这里定义下三种方式,方便下面说明。

  • xcodebuild xcrun(xcodebuild build和xcrun)
  • 只用xcodebuild(archive和exportArchive),
  • Xcode。

使用 Automator

三种方式的对比

我使用xcodebuild xcrun、仅xcodebuild、Xcode三种分别对相同代码和配置进行操作,根据结果做比较:

  • xcodebuild xcrun

ipa:40.7MB,.app:93.3MB,编译耗时:8m31s,打包耗时:15s。

  • 仅xcodebuild

ipa:37.3MB,.app:74MB,.xcarchive:227.3MB,编译耗时:8m24s,打包耗时:26s。

  • Xcode

ipa:37.3MB,.app:74MB,.xcarchive:227.3MB,编译耗时:8m40s,打包耗时:30s。

Xcode生成的.xcarchive文件可以在以下路径看到:

/Users/double/Library/Developer/Xcode/Archives

可以看出,<u>仅使用xcodebuild的结果和使用Xcode编译打包的结果是一致的</u>,并且最终的ipa也可以正常安装使用。而第一种xcodebuild xcrun的结果略大些,但是ipa也是可以正常使用的。这时需要了解下他们的区别。

Automator创建的workflow可以和其他应用程序无缝衔接,在【服务】选项里面可以找到自己为某个目标定制的workflow。 

xcodebuild xcrun和仅xcodebuild的比较

  • 使用xcrun打包方式二产生的.xcarchive中的.app

打包生成的.ipa文件大小同样为37.3MB,与方式二使用Xcodebuild -exportArchive的结果一致!这样说明:使用xcrun的打包方法是正常的,和xcodebuild -exportArchive的结果一致,而且.ipa包仅和.app有关。那么说明,<u>这两种方式的不同仅在于xcodebuild build和xcodebuild archive之间的不同</u>。

  • 删除.xcarchive中其他文件然后exportArchive

这时命令提示错误,但是上面我们已经得出结论.ipa的生成只和.app有关,所以可能的原因是,这个exportArchive命令会检查.archive的完整性和正确性,防止生成的.archive不完整或者是伪造的。下面做个实验看下。

使用Automator为xcode定制一个【服务】很简单,所以并没有考虑为xcode开发一个插件。 

命令到底做了什么

根据命令运行时输出的内容,看下中间做了什么

  • xcrun -sdk iphoneos PackageApplication -v xxx.app -o xxx.ipa
Packaging application: '/xxx/xxx.app'Arguments: output=/xxx/xxx.ipa verbose=1 Environment variables:SDKROOT = /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS9.2.sdk......SHELL = /bin/bashOutput directory: '/xxx/xxx.ipa'Temporary Directory: '/var/folders/21/6s9bb23j0s1343pm7ltnlgpm0000gn/T/taOIiK9AyK' (will NOT be deleted on exit when verbose set)  /bin/cp -Rp /xxx/xxx.app /var/folders/21/6s9bb23j0s1343pm7ltnlgpm0000gn/T/taOIiK9AyK/PayloadProgram /bin/cp returned 0 : []### Checking original app  /usr/bin/codesign --verify -vvvv /xxx/xxx.appProgram /usr/bin/codesign returned 0 : [/xxx/xxx.app: valid on disk/xxx/xxx.xcarchive/Products/Applications/xxx.app: satisfies its Designated Requirement]Done checking the original app  /usr/bin/zip --symlinks --verbose --recurse-paths /Users/double/Desktop/1.ipa .Program /usr/bin/zip returned 0 : [ adding: Payload/   (stored 0%) adding: Payload/xxx.app/   (stored 0%) ......

主要检查了环境变量,然后验证签名,然后压缩(看到了吗,居然是/usr/bin/zip),后面adding的基本都是.nib和.png等的压缩。看起来.archive只是一种压缩形式,包含了.app、.dSYM、.plist和其他一些文件。

这里的codesign工具就是签名相关的,可以查看说明:

SYNOPSIS codesign -s identity [-i identifier] [-r requirements] [-fv] [path ...] codesign -v [-R requirement] [-v] [path|pid ...] codesign -d [-v] [path|pid ...] codesign -h [-v] [pid ...]

-s是签名,-v是验证。所以可以在.app生成后再签名。

  • xcodebuild clean

清理工作,根据参数删除指定的workplace、target、configuration(release或debug) 的中间文件,都是工程目录下的build文件夹。

  • xcodebuild archive

下面是里面主要的步骤:

  1. Create product structure 创建.app文件
  2. CompileC 编译文件(clang编译,指定了编译的SDK版本和指令集)
  3. Ld
  4. CreateUniversalBinary
  5. CompileStoryboard
  6. CompileAssetCatalog
  7. ProcessInfoPlistFile (builtin-infoPlistUtility )
  8. GenerateDSYMFile (dsymutil )
  9. LinkStoryboards
  10. Strip
  11. ProcessProductPackaging (builtin-productPackagingUtility )
  12. CodeSign (codesign --force --sign)
  13. Validate (builtin-validationUtility )

呼呼写了这么多,终于到总结部分了。这个过程学到了很多东西,脚本成果确实方便了很多,减少了编译打包过程中人工监守、人工操作的成本,并且测试和提交到appStore的包都验证过可用。

-END-欢迎到我的博客交流:

打开Automator

新建一个service 

图片 4

修改服务需要的输入、选取需要服务的应用 

图片 5

加入流程一 

Automator应用界面左侧,打开资料库面板,点击【变量】,在搜索框中输入“path”,选择目标路径变量,拖拽到中间区域 

图片 6

拖拽到中间区域 

图片 7

选取项目工程根路径 

在 Automator 应用界面的下方,双击刚才【Destination Path】,在弹出面板中选择工程路径,选择后点击【完成】 

图片 8

加入流程二 

automator应用界面左侧,打开资料库面板,点击【操作】,在搜索框中输入“applescript”,选择运行AppleScript,拖拽到中间区域步骤1的下方 

图片 9

拖拽到中间区域 

图片 10

编辑 Applescript 

在 代码框中输入以下内容 

on run {input, parameters}

tell  application  "Terminal"

    activate

do  script  "cd "  &  input  &  " && . BuildScript/xcode-archive-release.sh"

end  tell

return  input 

end  run

脚本文件 xcode-archive-release.sh 我放到了工程目录的 BuildScript 文件夹里面 

这段 Applescript 脚本做的事就是 打开 Terminal,cd 到工程目录,运行BuildScript文件夹里面的脚本文件

最终看起来是这个样子的 

图片 11

最后,保存文件,输入文件名字就可以了。打开xcode,看看是否有了新的 service 选项

资源下载

上传到 iTunesconnect shell 脚本

Automator workflow文件

下载的脚本文件解压后,放到项目里,与 xxx.xcworkspace(xxx.xcodeproj) 同一级

修改 xcode-archive-release.sh 里面的配置(见配置修改

修改 release_exportOptions.plist 里面的 teamID

下载下来的 workflow 文件不用解压,用Automator打开,修改工程目录(参考使用 Automator

配置修改

打开 Terminal ,cd 到工程目录下,运行命令xcodebuild -list

$:xcodebuild -list

Targets:        

                XXXXXX        

                XXXXXXTests    

Build Configurations:        

                Debug

                Release

If  no build  configuration  is  specified  and  -scheme  is   not  passed  then  "Release"  is  used.    

Schemes:       

 XXXXXX

archiveName 

打包 archive 文件的名字(不用后缀) 

workspaceName 

工程文件的名字(需要后缀) 

scheme 

运行命令xcodebuild -list得到的Schemes,可能是一个列表,选一个你需要的 

codeSignIdentity 

形如:iPhone Distribution: xxxx Inc. (xxxxxxx) 

进入Build Settings, 编辑Code Signing identity成打release包需要的,再点击一下刚才选中的选项,弹出框中点击Other就可以获得形如iPhone Distribution: xxxx Inc. (xxxxxxx)的数据 

appStoreProvisioningProfile 

形如:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx 

获取方法与上面类似,最终获得形如xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx的数据 

configuration 

值为:Release 

运行命令xcodebuild -list得到的Build Configurations,有两个选项,打release包,所以值为Release 

exportOptionsPlist 

存放release_exportOptions.plist文件的相对路径 

如果下载到的BuildScript文件夹存放到项目根目录,其值为BuildScript/release_exportOptions.plist

ipaPath 

导出ipa文件的路径 

altool工具回到该路径获取需要上传的ipa文件,其值应为${PWD}/build/${archiveName}/${scheme}.ipa

appleid 

开发者账号(邮箱) 

applepassword 

开发者账号的密码

最后

本文讲述了Automator工具创建自动化流程,这仅仅是Automator的一部分。 

善用Automator,工作会更轻松。

本文由星彩网app下载发布于计算机编程,转载请注明出处:四处集成与不断分发,自动打包ipa并导出

TAG标签: 星彩网app下载
Ctrl+D 将本页面保存为书签,全面了解最新资讯,方便快捷。