多应用+插件架构,代码干净,二开方便,首家独创一键云编译技术,文档视频完善,免费商用码云13.8K 广告
# 自动打包 [TOC] *** # 参考: https://www.jianshu.com/p/6b4eb3666905 - (简书)LeeJay:【iOS打ipa包】使用终端实现自动打包 https://www.jianshu.com/p/0f0ad5f3ecd1 - (简书)全力以赴打酱油:实战fir脚本打ipa包 https://www.jianshu.com/p/ddb1cc17aa7e - (简书)KyXu:从 xcarchive 到分发的 ipa https://www.jianshu.com/p/490441391db6 - tangjuanj:多应用自动打包 https://www.cnblogs.com/tangjuanj/p/6720017.html *** # 配置准备 *** 1. 安装OS X command line tools ``` xcode-select --intall ``` 2. 安装fir-cli ``` gem install fir-cli ``` 3. 登录fir.im 在终端中输入 ``` fir login ``` 4. 获取fir 的 api token # 打包原理 基础命令: xcodebuild : 通过工程文件,生成 app 文件。 xcrun : 通过 app 文件,来生成 ipa 文件。(包含了签名的过程) xcarchive文件:是中间文件,需要export出ipa文件。 有两种方法来生成我们需要的 ipa 包。 1. 使用 xcodebuild 命令来编译我们的项目生成 app,然后再用 xcrun 将 app 转 ipa。 2. 使用 xcodebuild archive 命令来直接生成我们需要的 ipa。 虽然现在网上几乎都是使用 xcodebuild + xcrun 来来生成 ipa 包,不过既然官方说 PackageApplication is deprecated,那还是推荐使用第二种方法,一步到位。 打包步骤 ## 方法一:`xcodebuild` + `xcrun` 使用xcodebuild命令打包成 .app 文件这里以我们的 DemoTest 为例,实际应用时,请替换。 1. 打开终端, cd 到工程文件夹下。 `cd /Users/xxx/DemoTest` 2. 继续在终端输入下面命令行并执行: `xcodebuild -project DemoTest.xcodeproj -target DemoTest -configuration Release` 3. 编译成功会看到终端输出 Bulid Success。工程目录下会多出一个 build 文件夹, build 文件夹下有一个 DemoTest 的 .app 。 这个过程比较长,打印的日志也比较多 > 实际上我们直接使用 Xcode 编译工程之后也会在模拟器对应的沙盒路径下生成 .app 文件。 4. 把 app 文件打包为 ipa 文件 ``` xcrun -sdk iphoneos -v PackageApplication ./build/Release-iphoneos/DemoTest.app -o ~/Desktop/DemoTest.ipa ``` `-v` 对应的是 .app 文件的相对路径; `–o` 对应 ipa 文件保存的路径和文件名。 *** 使用上述方法可能会报错: `xcrun: error: unable to find utility "PackageApplication", not a developer tool or in PATH` 说明 PackageApplication 已经被弃用了。 不过其实这一步可以几乎等价于将 xx.app 放入一个 payload 的文件夹下然后压缩文件夹为 xx.ipa,当然这样做缺失一些信息,不过并不影响程序的运行。 升级了Xcode9之后,发现苹果把PackageApplication这个东西给删了 *** ## 方法二:`archive` + `exportArchive` 1. archive ``` xcodebuild archive -workspace /Users/MelissaShu/Documents/iOS/MS-Git/KYExpress_Internal_Plus/kyExpress_Internal.xcworkspace -scheme kyExpress_Internal -configuration Release -archivePath /Users/MelissaShu/Desktop/KYEInnerIPA/kyExpress_Internal.xcarchive ``` | xcpretty 2. exportArchive Xcode9 的打包需要指定以下信息,才能完成export操作: - provisioningProfiles - compileBitcode - method - signingCertificate - signingStyle - stripSwiftSymbols - teamID - thinning ``` ``` 语法如下: ``` xcodebuild -exportArchive -archivePath xcarchivepath -exportPath destinationpath -exportOptionsPlist path ``` ``` xcodebuild -exportArchive -archivePath /Users/MelissaShu/Desktop/KYEInnerIPA/kyExpress_Internal.xcarchive -exportPath /Users/MelissaShu/Desktop/KYEInnerIPA/kyExpress_Internal1 -exportOptionsPlist /Users/MelissaShu/Desktop/KYEInnerIPA/ExportOptions.plist ``` *** # 生成 `exportOptionsPlist` 文件 1. 执行打包操作:Product -> Archive ![Archive](/Users/MelissaShu/ios/images/Archive.png) 2. 打包完成后执行export操作(其中会需要你手动选择你的相关provison profile等信息),Xcode9会自动生成exportOptionsPlist文件,同时拷贝到你生成的ipa包的同级目录下。 ![ExportOption](/Users/MelissaShu/ios/images/ExportOption.png) 比如,我的list 内容如下: ``` <?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>compileBitcode</key> <false/> <key>method</key> <string>development</string> <key>provisioningProfiles</key> <dict> <key>com.InternalkyExpresstest.www</key> <string>0823profile</string> </dict> <key>signingCertificate</key> <string>iPhone Developer</string> <key>signingStyle</key> <string>manual</string> <key>stripSwiftSymbols</key> <true/> <key>teamID</key> <string>5T6LG5NT8U</string> <key>thinning</key> <string>&lt;none&gt;</string> </dict> </plist> ``` *** 方法三: ``` 最简单的打包命令如下:firbuild_ipa这样会自动打包ipa,不过会输出到一个临时目录,如Results at '/var/folders/ky/syfrlzpn2bb8fmn5pr51tstm0000gp/T/d20160306-64805-akfs4h/1457249301.ipa'对于一个CI平台来说,这样的存放路径毫无意义,所以一般会这样写firbuild_ipa-o ./ ``` *** *** # 各格式简要说明 ## `.xcarchive` - Xcode Archive - 由 Xcode 进行 Archive 操作产生的结果,出现在 Xcode Organizer 中 - 主要包含 `.dSYM`, `.app`, `.dylib`(针对 Swift) - 用于生成 .ipa 文件 ## `.ipa`(Xcode 产出) - iPhone Application Archive - 主要包含`.app`, `.dylib`(针对 Swift) - 最终从本地 upload 到 iTunes Connect 的文件 ## `.ipa`(iTunes 下载) - iPhone Application Archive - 主要包含 .app iTunesMetadata iTunesArtwork - iTunes 用于管理应用软件安装包的形式 ## `.app` - Applicaiton; - 主要包含图片、语言文件等资源,以及动态库和 Unix 可执行文件; - 安装到 iOS 设备的文件的格式 ## `.appex` 在iOS 8系统之前,每一个app在物理上都是彼此独立的,app之间不能互访彼此的私有数据。而在引入扩展(Extension)之后,其他app可以与扩展进行数据交换。基于安全和性能的考虑,每一个扩展运行在一个单独的进程中,它拥有自己的bundle, bundle后缀名是.appex。扩展bundle必须包含在一个普通应用的bundle的内部。 *** # 状态的变化 ## 从 xcarchive 到 ipa 在进行 Archive 操作之前,我们就可以在 Xcode 导航栏的 Products 目录中看到 .app 文件,extension target 对应的是 .appex 文件,所以归档出 .xcarchive 并不是一个非常复杂的操作,只需要编译、链接、简单的签名,如果是 Swift 项目的话还需要拷贝一下标准库。 我们查看 .xcarchive 里面的内容是通过“显示包内容”看见的,而 .ipa 则需要像 .zip 文件一样解压,那么也可以理解为什么打包出 ipa 文件相对耗时了,尤其是 Swift 项目,不光要进行压缩操作,要 processing,一堆原生动态库加上第三方 framework 还要轮着等着签名。 这些保证了 ipa 文件不能被模拟器装上(没有 x86 架构),只能被 iOS 设备安装,你买的应用程序发给别人,别人并不能直接装上。从兔兔助手等平台安装的盗版软件一定是被重新签名过的。 (由于 ipa 文件上传到 iTunes Connect 之后,还会被重新处理,所以个人尚且不知道后续的处理过程还进行过怎样的签名工作) 所以 ipa 文件才可以作为加密文件放在软件商店,xcarchive 不可以。 从 Xcode 产出的 ipa 到用户下载的 ipa 如图是我开发的一款软件打包过程的各个状态,可以看到压缩状态的 ipa 文件是体积最小的。如果将 ipa 文件解压成文件夹,它的体积会和 xcarchive 文件很接近,因为它内部包含了比它本身还要大的整个 .app 包。 然后我分别通过 AppStore 和 TestFlight 安装了我上传的软件,结果都只占用了大约 15M 的空间。 前面提到,下载到设备的是 ipa,安装到设备的是 app。但看图,会发现 TestFlight 页面展示的体积和另外三张图相去甚远,30M+。仔细分析下: iPhone 5S 推出之后,iOS 设备指令集从 armv6、armv7、armv7s 一路干到了 arm64,这么些个不同的设备安装到本地的文件肯定不一样吧 同一设备不同系统,安装的文件也不一样吧 Xcode 一次只产出一个 ipa,但是考虑到这款软件支持的系统版本数量和设备种类数量,可能最终几十种不同的 iOS 环境(自造词,系统版本或设备型号不同都算环境不同),从同一个 AppStore 页面,下载了几十个不同的 ipa 文件 尝试发布过 app 的开发者都知道,上传 ipa 文件完成之后,还要等待一段时间,才能在 iTunes Connect 页面看见一个“构建版本”。虽然不知道这个“构建版本”在 Apple 的服务器里面具体都有哪些东西,但至少应该包含一大堆的 ipa 文件,分别指定了对应什么系统版本、什么设备型号 在这个过程中 ipa 文件的体积发生了很大变化,App Thining 也发生在这个过程中。 至此可以看出,AppStore 页面显示的体积应该是预估的应用安装到设备的体积,而不是你下载这款软件所耗费的流量。这也解释了我之前尝试用剩 1G 存储的 iPad 去装一个 AppStore 显示 大小不到 1G 的游戏,为什么会装不上,因为下载到 iPad 的文件实际可能大于 1G。 TestFlight 里面显示的 30M+,肯定是经过 iTunes Connect 处理过的 ipa,但考虑到 .ipa 文件并不会比安装到设备的 .app 包体积更小,个人认为这是解压过后的 ipa 文件的体积。 我的 app 是如何一步一步变小的 未处理的 .app - 85.6 M (加入动态库、.dSYM 等) xcarchive - 167.7 M 未处理的 ipa 文件夹 - 172 M (经过类似 zip 压缩) 未处理的 .ipa - 70.8 M(开发者感受到的体积) (个人推测)处理后的 ipa 文件夹- 约 30M(用户下载需要耗费的流量) 处理后的 .app - 约 15M(最终占用用户设备体积) 备注 App Thining 包含 Slicing、Bitcode 和 On-Demand Resources,其中 Slicing 是默认启用、无法关闭的,但只在 iOS 9.0.2 之后有效,后面两个选项在 Xcode 中默认开启,可以手动关闭。 这是 Xcode 产物体积与用户下载到设备中的软件体积差距较大的主要原因。 *** 想用exportArchive就不能指定scheme,但是想要用workspace编译又要指定scheme,死循环了咋办?! ``` ```