内网搭建ipa下载网站

参考文章:

iPhone上使用 itms-services 协议安装 IPA 包

如何创建一个自签名的SSL证书(X509)

持续化集成中,为了应对多项目并行开发的测试需求,需要提供一个ios端的安装包平台。

想要实现自主分发,主要依赖itms-services服务

  1. 首先iphone捕捉到itms-services://开头的链接如itms-services://?action=download-manifest&url=https://ip:port/plists/xxxxxx.plist
  2. 然后根据url参数去获取对应的plist文件
  3. 根据plist文件里的配置去下载ipa

所以我们需要提供的主要文件便是plist文件和ipa文件

Xcode 生成plistipa

首先我们先看xcode是如何生成plist文件的:

打开 Xcode -> Product -> Archive -> Distribute App

非企业证书选择Ad Hoc


这里的App URL便是下载ipa的地址

最终会生成一个文件夹:

1
2
3
4
5
6
.
├── DistributionSummary.plist
├── ExportOptions.plist
├── xxx.ipa
├── Packaging.log
└── manifest.plist

其中manifest.plist便是我们所需要的文件:

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
<?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>items</key>
<array>
<dict>
<key>assets</key>
<array>
<dict>
<key>kind</key>
<string>software-package</string>
<key>url</key>
<string>https://ip:port/ipa/xxx.ipa</string>
</dict>
<dict>
<key>kind</key>
<string>display-image</string>
<key>url</key>
<string>https://test1/ios</string>
</dict>
<dict>
<key>kind</key>
<string>full-size-image</string>
<key>url</key>
<string>https://test1/ios1</string>
</dict>
</array>
<key>metadata</key>
<dict>
<key>bundle-identifier</key>
<string>com.xxx</string>
<key>bundle-version</key>
<string>2.0.5</string>
<key>kind</key>
<string>software</string>
<key>title</key>
<string>Hestia</string>
</dict>
</dict>
</array>
</dict>
</plist>

搭建Demo页面

我们拿到这两个文件可以在电脑上搭一个简单的页面尝试下载。

打开Mac自带apache服务,这里要注意一定要开启https,因为itms-services://不支持http

  1. 生成自签名证书
1
2
3
openssl genrsa -des3 -out server.key 2048
openssl req -new -key server.key -out server.csr
openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt
  1. mac 开启apache ssl
    • /etc/apache2/httpd.config
1
2
3
LoadModule ssl_module libexec/apache2/mod_ssl.so
Include /private/etc/apache2/extra/httpd-vhosts.conf
Include /private/etc/apache2/extra/httpd-ssl.conf
  • /etc/apache2/extra/httpd-ssl.conf
1
2
3
这里证书路径为默认的,建议将上一步的证书放在这个路径下,也可修改为自定义路径
SSLCertificateFile "/private/etc/apache2/server.crt"
SSLCertificateKeyFile "/private/etc/apache2/server.key"
  • /etc/apache2/extra/httpd-vhosts.conf
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<VirtualHost *:80>
ServerAdmin xxxx@xxxxxx.com
DocumentRoot "/Library/WebServer/Documents"
ServerName ip address
ErrorLog "xxxxx/apache2/logs/error_log"
CustomLog "xxxxx/apache2/logs/access_log" common
</VirtualHost>
<VirtualHost *:443>
SSLEngine on
SSLCipherSuite ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP:+eNULL
SSLCertificateFile /private/etc/apache2/server.crt
SSLCertificateKeyFile /private/etc/apache2/server.key
ServerName ip address
DocumentRoot "/Library/WebServer/Documents"
</VirtualHost>
  • 配置改完之后可以在终端执行sudo apachectl configtest验证是否通过
  • 然后执行sudo apachectl,如果已经有在运行的httpd服务,先把之前的kill

这个时候在浏览器打开https://localhost便可以看到页面了

我们打开指定的网页目录/Library/WebServer/Documents,编辑一下html文件,然后将xcode生成的plistipa放到路径下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<a href="itms-services://?action=download-manifest&url=https://xxxx:443/plist/manifest.plist">下载</a>
<a href="Cer/server.crt">证书</a>
</body>
</html>
1
2
3
4
5
6
7
8
9
10
.
├── Cer
│   └── server.crt
├── PoweredByMacOSX.gif
├── PoweredByMacOSXLarge.gif
├── index.html.en
├── ipa
│   └── xxx.ipa
└── plist
└── manifest.plist

在手机上访问刷新页面,点击新增的a标签,此时会提示无法连接到服务器。

我们需要手机信任当前服务器证书

  • 将上面生成的ssl证书中的server.crt放到网页路径下
  • 然后先点击证书,安装并信任后,再点击下载

至此为止,简单的Demo已经完成了,下一步便是完善了

搭建iOS下包平台

整个流程如下图:

  1. 代码提交后,通过jenkins打包ipa
  2. jenkinsipa上传至ipa存储服务器
  3. 接收到ipa后生成plist文件
  4. 将信息写入sql供查询使用
  5. 搭建一个前端页面供测试下载

服务端部分

服务端部分使用了python3主要依赖了flask框架

代码地址(ps:代码没有分模块,没有拆分,没有加异常判断)

1
2
3
4
5
6
7
8
upload : 上传接口,接收package,job_name,build_number
get_ipa_info: 获取接口,返回不同job_name的列表,接收page,page_index
get_ipa_info_by_job_name: 根据job_name获取当前的所有ipa列表
可以使用下面curl测试:
curl "https://ip:port/upload" -F "package=@xxx.ipa" -F "job_name=xxx" -F "build_number=1" --insecure

数据库部分

数据库部分主要使用了mysql

前端部分

前端部分主要使用vue,由同事帮忙开发,源码

最终效果:


这就是简单的一个安装包平台的搭建流程,对于企业账号来说,可以无限分发,但对于个人开发者账号的话,只有添加过的设备才能安装。

搭建好平台后,我们只需要在jenkins上面打包成功之后,添加一个脚本将ipa发送给服务器就好了,可以直接使用curl命令

最终我们将这个网页发给测试使用,就可以满足多项目并发时快速打包的需求了!!!