flutter一键打包ipa、apk安装包 上传蒲公英

经验证,flutter build iOS打出的ipa包太大,用xcodebuild打包正常,支持设置代码混淆。iOS如果因为签名原因打包失败,先用Xcode正常打一次就行。

直接上脚本:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
## 计时
SECONDS=0

# 打包类型 1:android 2:ios any:其它全部
platform=0

# Xcode12开始需要设置导出ipa的名字
project_name="flutter_easy_example"
## 蒲公英 APIKey https://www.pgyer.com/account/api
pgyer_api_key=""
## 蒲公英 下载地址后缀
pgyer_subfix_url=""
## 蒲公英 安装密码
pgyer_pwd=""

# 不使用代码混淆
#obfuscate=""
# 开启代码混淆
obfuscate="--obfuscate --split-debug-info=app"

# 选择打包类型
read -n1 -p "设置打包类型 1:android 2:ios any:其它全部 (5s后自动执全部打包) [1/2/any]? " -t 5 answer
platform=${answer}

echo "清理 build"
find . -d -name "build" | xargs rm -rf
flutter clean

echo "开始获取 packages 插件资源"
flutter packages get

# iOS
build_ios() {
cd ios
project=`find . -name *.xcodeproj | awk -F "[/.]" '{print $(NF-1)}'`

## true or false 默认true
workspace_flag="true"

## Release or Debug 默认Release
configuration="Release"

## Bitcode开关 默认打开
compileBitcode=true

## 签名方式 默认自动签名,如果打包失败,先用Xcode打一次就正常了
signingStyle="automatic"

## 签名方式
### development
### ad-hoc
### app-store
### enterprise
methodStyle="ad-hoc"

## 打包导出目录
path_app="../app"

## 工作目录 build目录在.gitignore添加忽略
path_build="build"

path_archive="${path_build}/${project}.xcarchive"

path_export_options="${path_build}/ExportOptions.plist"

if [ -d "${path_build}" ]
then
echo "目录${path_build}已存在"
else
echo "创建目录${path_build}"
mkdir -pv "${path_build}"
fi

funcExpertOptionFile() {
if [ -f "$path_export_options" ]
then
rm -rf "$path_export_options"
fi

/usr/libexec/PlistBuddy -c "Add :compileBitcode bool $compileBitcode" "$path_export_options"
/usr/libexec/PlistBuddy -c "Add :signingStyle string $signingStyle" "$path_export_options"
/usr/libexec/PlistBuddy -c "Add :method string $methodStyle" "$path_export_options"
}

## 创建ExportOptions.plist文件
funcExpertOptionFile

if $workspace_flag
then
## 清理工程
xcodebuild clean -workspace ${project}.xcworkspace \
-scheme ${project} \
-configuration ${configuration}

## 归档
xcodebuild archive -workspace ${project}.xcworkspace \
-scheme ${project} \
-configuration ${configuration} \
-archivePath ${path_archive}
else
## 清理工程
xcodebuild clean -project ${project}.xcworkspace \
-scheme ${project} \
-configuration ${configuration}

## 归档
xcodebuild archive -project ${project}.xcworkspace \
-scheme ${project} \
-configuration ${configuration} \
-archivePath ${path_archive}
fi

## 判断归档结果
if [ -d "${path_archive}" ]
then
echo "** Finished archive. Elapsed time: ${SECONDS}s **"
echo
else
exit 1
fi

## 导出ipa
xcodebuild -exportArchive \
-archivePath ${path_archive} \
-exportPath ${path_app} \
-exportOptionsPlist ${path_export_options}

## ipa路径
file_ipa="${path_app}/${project}-$(date "+%Y%m%d%H%M").ipa"
if [[ -n "${project_name}" ]]
then
mv "${path_app}/${project_name}.ipa" "${file_ipa}"
else
mv "${path_app}/${project}.ipa" "${file_ipa}"
fi

## 判断导出ipa结果
if [ -f "${file_ipa}" ]
then
echo "** Finished export. Elapsed time: ${SECONDS}s **"
rm -rf "$path_build"
echo $file_ipa
say "iOS打包成功"

if [[ -n "${pgyer_api_key}" ]]
then
#上传到pgyer
echo "正在上传到蒲公英..."
echo
curl -F "file=@${file_ipa}" -F "_api_key=${pgyer_api_key}" -F "buildInstallType=2" -F "buildPassword=${pgyer_pwd}" -F "buildUpdateDescription=脚本自动上传" https://www.pgyer.com/apiv2/app/upload
# rm -rf ${file_ipa}
echo
say "iOS上传蒲公英成功"
echo
if [[ -n "${pgyer_subfix_url}" ]]
then
open https://www.pgyer.com/${pgyer_subfix_url}
fi
else
open $path_app
fi
else
echo "遇到报错了😭, 打开Xcode查找错误原因"
say "iOS打包失败"
exit 1
fi

echo "------------------------------------------------------------------------------"
echo "🎉 Congrats"

echo "🚀 ${project} successfully published"
echo "📅 Finished. Elapsed time: ${SECONDS}s"
echo "🌎 https://octmon.github.io"
echo "👍 Tell your friends!"
echo "------------------------------------------------------------------------------"

echo

cd ..
}

##==================================apk==================================
if [[ ${platform} -ne 2 ]]; then
echo "开始build apk"
flutter build apk $obfuscate --release --verbose #--no-codesign
echo "build apk已完成"

file_apk=android-$(date "+%Y%m%d%H%M").apk

cp -r build/app/outputs/apk/release/app-release.apk app/$file_apk

if [[ -f app/${file_apk} ]]
then
say "android打包成功"

if [[ -n "${pgyer_api_key}" ]]
then
#上传到pgyer
echo "正在上传到蒲公英..."
echo
curl -F "file=@app/${file_apk}" -F "_api_key=${pgyer_api_key}" -F "buildInstallType=2" -F "buildPassword=${pgyer_pwd}" -F "buildUpdateDescription=脚本自动上传" https://www.pgyer.com/apiv2/app/upload
# rm -rf app/${file_ipa}
echo
say "android上传蒲公英成功"
echo
if [[ -n "${pgyer_subfix_url}" ]]
then
open https://www.pgyer.com/${pgyer_subfix_url}
fi
else
open app
fi
else
echo "遇到报错了😭, 打开Android Studio查找错误原因"
say "android打包失败"
fi

echo "📅 Finished. Elapsed time: ${SECONDS}s"
fi
##==================================apk==================================

##==================================ipa==================================
if [[ ${platform} -ne 1 ]]; then
echo "开始build ios"
flutter build ios $obfuscate --release --verbose #--no-codesign
echo "build ios已完成"

build_ios
fi
##==================================ipa==================================