iOS开发系列-Shell脚本生成IPA
概述
在公司开发到了测试阶段需要频繁打包交付给测试,看似简单的工作,重复的流程总是感觉不是那么好,我们可以借助苹果提供的编译指令编译项目。
自动化脚本编译打包IPA
常见的iOS项目就是基于xcodeproj。目前大部分公司项目都是用CocoaPod 管理第三方库,也就是项目基于xcworkspace 。这两种项目在编译时候命令有一些区别,下面分别写两种脚本供参考。
普通项目编译
PackageApplication方式生成ipa的方式苹果已经不建议使用了,取而代之的是xcodebuild -exportArchive。
#!/bin/bash
ZWProjectName="TestProj"
ZWScheme="TestProj"
ZWConfiguration="Release"
ZWDate=`date +%Y%m%d_%H%M`
ZWWorkspace=`pwd`
echo "workspace=$ZWWorkspace-----------------------"
ZWBuildDir="$ZWWorkspace/build" #build路径
ZWBuildTempDir="$ZWBuildDir/temp/$ZWDate" #构建过程中的文件
HCIpaDir="$ZWBuildDir/ipa" #生成ipa文件路径
:<<!
#编译 链接 签名 生成app
#如果要构建workspace,你必须指定-workspace和-scheme参数。
xcodebuild \
-workspace "$ZWWorkspace/$ZWProjectName.xcodeproj/project.xcworkspace" \
-scheme "$ZWScheme" \
-configuration "$ZWConfiguration" \
clean \
build \
-derivedDataPath "$ZWBuildTempDir"
#CODE_SIGN_IDENTITY=证书
#PROVISIONING_PROFILE=描述文件UUID
#生成ipa 本质主要是对生成app进行压缩成ipa
xcrun -sdk iphoneos \
-v PackageApplication "$ZWBuildTempDir/Build/Products/$ZWConfiguration-iphoneos/$ZWProjectName.app" \
-o "$HCIpaDir/$ZWDate.ipa" #这里反复报错 如果输出的目录不存在就报错 Unable to create '....." 解决办法 手动穿件输出测文件夹层级结构
#清除构建的文件
rm -rf $ZWBuildDir/temp
open $HCIpaDir
!
#-------PackageApplication已经不推荐使用了 warning: PackageApplication is deprecated, use `xcodebuild -exportArchive` instead.-----
xcodebuild archive \
-workspace "$ZWWorkspace/$ZWProjectName.xcodeproj/project.xcworkspace" \
-scheme "$ZWScheme" \
-configuration "$ZWConfiguration" \
-archivePath "$ZWBuildTempDir/$ZWProjectName.xcarchive"
CODE_SIGN_IDENTITY="" #证书
PROVISIONING_PROFILE="" #描述文件UUID
xcodebuild \
-exportArchive \
-archivePath "$ZWBuildTempDir/$ZWProjectName.xcarchive" \
-exportPath "$HCIpaDir/$ZWDate/" \
-exportOptionsPlist "./exportOptionsPlist.plist" \
#CODE_SIGN_IDENTITY="" #证书
#PROVISIONING_PROFILE="" #描述文件UUID
#这里不需要设置证书
#编译流程
#1.首先看ZWConfiguration是Release还是Debug
#2.如果是Release那么就去General->Signing(Release)的Provisioning Profile编译
#3.如果是Debug那么就去General->Signing(Debug)的Provisioning Profile编译
#如果是发布store的包 只需将配置设置General->Signing(Release)的Provisioning Profile选择Store 描述文件
:<<!
编写过程遇到的报错:
1.exportOptionsPlist.plist文件的编写
xcode直接先Archive 拿到ExportOptions.plist
2.下面这个报错纠结了我好久,
# Error Domain=NSCocoaErrorDomain Code=384
# 详细报错
#2018-03-06 17:18:43.013 xcodebuild[2836:4964380] [MT] IDEDistribution: -[IDEDistributionLogging _createLoggingBundleAtPath:]: Created bundle at path '/var/folders/rj/k7nnqyqd5xz7_lh9s2dc9z4m0000gn/T/TestProj_2018-03-06_17-18-43.012.xcdistributionlogs'.
#2018-03-06 17:18:43.476 xcodebuild[2836:4964380] [MT] IDEDistribution: Step failed: <IDEDistributionPackagingStep: 0x7f8ca5d414e0>: Error Domain=NSCocoaErrorDomain Code=3840 "No value." UserInfo={NSDebugDescription=No value., NSFilePath=/var/folders/rj/k7nnqyqd5xz7_lh9s2dc9z4m0000gn/T/ipatool-json-filepath-U38ZKM}
#error: exportArchive: The data couldn’t be read because it isn’t in the correct format.
#Error Domain=NSCocoaErrorDomain Code=3840 "No value." UserInfo={NSDebugDescription=No value., NSFilePath=/var/folders/rj/k7nnqyqd5xz7_lh9s2dc9z4m0000gn/T/ipatool-json-filepath-U38ZKM}
#** EXPORT FAILED **
# 最终发现了问题关闭compileBitcode 设置为NO
!
#通过蒲公英提供的上传应用 API,调用系统的 curl 命令来上传应用。
#FilePath="$HCIpaDir/$ZWDate/${ZWScheme}.ipa"
#UKey="User key" #开发者的用户 Key,在应用管理-API中查看
#ApiKey="API key" #是开发者的 API Key,在应用管理-API中查看 注意不是APPKey
#chmod -R 777 "${FilePath}"
#curl \
#-F "file=@${FilePath}" \
#-F "uKey=${UKey}" \
#-F "_api_key=${ApiKey}" \
#https://www.pgyer.com/apiv2/app/upload
基于CocoaPod的工程脚本编译
对于使用工作空间管理工程,唯一不同的是在xcodebuild archive需要加参数-workspace 与scheme 。
#!/bin/bash
ZWProjectName="lifeCristal"
ZWScheme="lifeCristal"
ZWConfiguration="Release"
ZWDate=`date +%Y%m%d_%H%M`
ZWWorkspace=`pwd`
echo "workspace=$ZWWorkspace-----------------------"
ZWBuildDir="$ZWWorkspace/build" #build路径
ZWBuildTempDir="$ZWBuildDir/temp/$ZWDate" #构建过程中的文件
HCIpaDir="$ZWBuildDir/ipa" #生成ipa文件路径
xcodebuild archive \
-workspace "$ZWWorkspace/$ZWProjectName.xcworkspace" \
-scheme "$ZWScheme" \
-configuration "$ZWConfiguration" \
-archivePath "$ZWBuildTempDir/$ZWProjectName.xcarchive"
CODE_SIGN_IDENTITY="" #证书
PROVISIONING_PROFILE="" #描述文件UUID
xcodebuild \
-exportArchive \
-archivePath "$ZWBuildTempDir/$ZWProjectName.xcarchive" \
-exportPath "$HCIpaDir/$ZWDate/" \
-exportOptionsPlist "./exportOptionsPlist.plist" \
CODE_SIGN_IDENTITY="" #证书
PROVISIONING_PROFILE="" #描述文件UUID
FilePath="$HCIpaDir/$ZWDate/${ZWScheme}.ipa"
UKey="013cca42bc5347715f895cfc8061f75f"
ApiKey="4861c59806712e3473c867520884236f"
chmod -R 777 "${FilePath}"
curl \
-F "file=@${FilePath}" \
-F "uKey=${UKey}" \
-F "_api_key=${ApiKey}" \
https://www.pgyer.com/apiv2/app/upload
证书跟描述文件UUID获取
- 获取本机可用的开发证书
security find-identity -v -p codesigning

- 获取描述文件的UUDI
我们Mac电脑所有描述文件目录个人资源库/MobileDevice/Provisioning Profiles/
执行命令
/usr/bin/security cms -D -i 描述文件路径

通常描述文件的名称就是描述文件的UUID。
exportOptionsPlist.plist文件获取
这个文件中的内容会随着Xode的版本而发生改变。我这边做法是自己手动打包第一次,将生成的ExportOptions.plist改名为exportOptionsPlist.plist。后续每次打包都是用这个plist就可以了。
创建的编译报错
在实际使用避免不了各种错误,下面对一些常见的错误解决。
Bitcode引发的错误

解决办法:在exportOptionsPlist.plist关闭Bitcode为NO。
iOS开发系列-Shell脚本生成IPA的更多相关文章
- iOS开发系列-Shell脚本编译SDK
Library静态库Shell脚本 #!/bin/bash #要build的target名 target_Name="IFlyMSC" #编译模式 Release.Debug bu ...
- iOS开发系列--Swift进阶
概述 上一篇文章<iOS开发系列--Swift语言>中对Swift的语法特点以及它和C.ObjC等其他语言的用法区别进行了介绍.当然,这只是Swift的入门基础,但是仅仅了解这些对于使用S ...
- iOS开发系列--Swift语言
概述 Swift是苹果2014年推出的全新的编程语言,它继承了C语言.ObjC的特性,且克服了C语言的兼容性问题.Swift发展过程中不仅保留了ObjC很多语法特性,它也借鉴了多种现代化语言的特点,在 ...
- iOS开发系列--App扩展开发
概述 从iOS 8 开始Apple引入了扩展(Extension)用于增强系统应用服务和应用之间的交互.它的出现让自定义键盘.系统分享集成等这些依靠系统服务的开发变成了可能.WWDC 2016上众多更 ...
- iOS开发系列--通知与消息机制
概述 在多数移动应用中任何时候都只能有一个应用程序处于活跃状态,如果其他应用此刻发生了一些用户感兴趣的那么通过通知机制就可以告诉用户此时发生的事情.iOS中通知机制又叫消息机制,其包括两类:一类是本地 ...
- iOS开发系列--数据存取
概览 在iOS开发中数据存储的方式可以归纳为两类:一类是存储为文件,另一类是存储到数据库.例如前面IOS开发系列-Objective-C之Foundation框架的文章中提到归档.plist文件存储, ...
- iOS开发系列--网络开发
概览 大部分应用程序都或多或少会牵扯到网络开发,例如说新浪微博.微信等,这些应用本身可能采用iOS开发,但是所有的数据支撑都是基于后台网络服务器的.如今,网络编程越来越普遍,孤立的应用通常是没有生命力 ...
- iOS开发系列--C语言之基础知识
概览 当前移动开发的趋势已经势不可挡,这个系列希望浅谈一下个人对IOS开发的一些见解,这个IOS系列计划从几个角度去说IOS开发: C语言 OC基础 IOS开发(iphone/ipad) Swift ...
- 【转】iOS开发系列--数据存取
原文: http://www.cnblogs.com/kenshincui/p/4077833.html#SQLite 概览 在iOS开发中数据存储的方式可以归纳为两类:一类是存储为文件,另一类是存储 ...
随机推荐
- Display与 Visibility的区别
隐藏元素的方法有: display:none或visibility:hidden visibility:hidden可以隐藏某个元素,但隐藏的元素仍需占用与未隐藏之前一样的空间.也就是说,该元素虽然被 ...
- C++——函数及调用
1.函数调用:实参初始化形参:控制权交给被调函数 2.函数返回(return语句):返回return中的值:控制权交回主函数 3.参数传递 传值 传引用 传指针 初始值 不变,拷贝给形参 可变,形 ...
- 2、获取APP CPU占用率
前面已经介绍过如何获取包名和主活动名.这里不再过多赘述.我们依旧采取两种方案实现APP CPU占有率 Windows下获取APP CPU占用率 adb shell "dumpsys cpui ...
- 9. DMA
9.1 介绍 Direct memory access(DMA) 直接存储器访问. 这两个DMA控制器总共有16个流(每个控制器8个),每个流用于管理来自一个或多个外围设备的内存访问请求.每个流总共可 ...
- 大数运算之 Java BigInteger 的基本用法
大数运算之 Java BigInteger 的基本用法 在程序设计竞赛中会遇到高精度运算的问题,C++没有高精度运算,只能手动模拟人工运算,手动实现高精度,而 java.math 包中的 BigInt ...
- Codeforces 1191A Tokitsukaze and Enhancement
题目链接:http://codeforces.com/problemset/problem/1191/A 思路:枚举 16 种情况输出最高的就行. AC代码: #include<bits/std ...
- Flask数据库的基本操作
Flask操作数据库基本操作 常用的SQLAlchemy字段类型 类型名 python中类型 说明 Integer int 普通整数,一般是32位 SmallInteger int 取值范围小的整 ...
- git stash封存分支 以及关于开发新功能的处理
有种情况,我们要修复项目的bug时,但别的分支有修改的代码,要修复的bug可能会影响(所有分支共用一个暂存区).可以单独创建一个bug分支,用于修复和提交bug,在修改前可以先stash封存分支修改的 ...
- 567. Permutation in String【滑动窗口】
Given two strings s1 and s2, write a function to return true if s2 contains the permutation of s1. I ...
- if控制器
因为比较的是字符串,所以要在两边加双引号哦