MBP搭建本地Https服务器实现ipa文件的下载

起因

2020年新春,本是阖家欢乐,走亲访友的好时节。没想到一场疫情改变了所有计划,本人刚好又处于风暴的中心湖北,按时返京是不太可能了,于是只得开启漫长的在家办公的旅程。回家时带了个mbp,没有带TypeC的装接头,没有办法真机调试,而我们的项目又不能在模拟器上运行,这样的工作环境想想就头大。只能是硬着头皮使用打包上传fir的方式进行开发和调试,但是村里的网络也不太给力,可能一次打包上传再到安装在真机上需要一个多小时,效率实在太低,于是开始思考有啥办法可能提高现在的效率,也就有了下面的实践经历。

经过

安装nginx

我是使用的nginx来搭建的https服务,因为之前也用它搭过rtmp服务,使用起来会比较顺手吧。推荐使用homebrew来安装。

安装完后使用一下命令来进行nginx的相关操作:

1
2
3
sudo nginx //启动Nginx
sudo nginx -s reload //重启Nginx
sudo nginx -s stop //快速停止Nginx

开启nginx成功后,在Safari里面输入http://127.0.0.1 应该就能正常访问到nginx自带的一个html了,接下来是支持https。

安装openssl

生成证书时需要使用openssl服务。同上,使用homebrew安装。

生成证书

推荐使用下面的脚本来生成:

1
2
3
4
5
6
cd /usr/local/etc/nginx # 进入希望生成证书和私钥的目录,这里我们选择nginx.conf所在目录
openssl genrsa -des3 -out 172.20.10.9.key 1024 # 创建服务器私钥,该命令会让你输入一个口令
openssl req -new -key 172.20.10.9.key -out 172.20.10.9.csr # 创建签名请求的证书(CSR)
cp 172.20.10.9.key 172.20.10.9.key.org
openssl rsa -in 172.20.10.9.key.org -out 172.20.10.9.key # 在加载SSL支持的Nginx并使用上述私钥时除去必须的口令
openssl x509 -req -days 365 -in 172.20.10.9.csr -signkey 172.20.10.9.key -out 172.20.10.9.crt # 最后标记证书使用上述私钥和CSR

每一句的具体作用参考上面的注释,这里的172.20.10.9是我电脑的内网IP,用来做证书名方便识别,在生成证书时,会需要输入密码和一些企业信息,其他的信息都可以随意(密码需要一致),重点:有一个Common Name字段信息需要和你服务器地址(我这里也就是我的内网IP)保持一致,因为在下载ipa进行证书校验时需要校验这两个是否一致,如果不一致会报:无法连接到“xxx”的错误

下面是openssl生成几个文件

配置nginx.conf

nginx.conf目录地址:

1
/usr/local/etc/nginx

具体配置项参考如下:

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
#user nobody;
worker_processes 1;
#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
#pid logs/nginx.pid;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
#log_format main '$remote_addr - $remote_user [$time_local] "$request" '
# '$status $body_bytes_sent "$http_referer" '
# '"$http_user_agent" "$http_x_forwarded_for"';
#access_log logs/access.log main;
sendfile on;
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 65;
#gzip on;
server {
listen 443 ssl;
server_name localhost ;
ssl_certificate 172.20.10.9.crt;
ssl_certificate_key 172.20.10.9.key;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
root /usr/local/etc/nginx/doki;
index download.html index.htm;
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
# proxy the PHP scripts to Apache listening on 127.0.0.1:80
#
#location ~ \.php$ {
# proxy_pass http://127.0.0.1;
#}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
#location ~ \.php$ {
# root html;
# fastcgi_pass 127.0.0.1:9000;
# fastcgi_index index.php;
# fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
# include fastcgi_params;
#}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
#location ~ /\.ht {
# deny all;
#}
}
# another virtual host using mix of IP-, name-, and port-based configuration
#
#server {
# listen 8000;
# listen somename:8080;
# server_name somename alias another.alias;
# location / {
# root html;
# index index.html index.htm;
# }
#}
# HTTPS server
#
#server {
# listen 443 ssl;
# server_name localhost;
# ssl_certificate server.crt;
# ssl_certificate_key cert.key;
# ssl_session_cache shared:SSL:1m;
# ssl_session_timeout 5m;
# ssl_ciphers HIGH:!aNULL:!MD5;
# ssl_prefer_server_ciphers on;
# location / {
# root html;
# index index.html index.htm;
# }
#}
include servers/*;
}

需要注意一下,上面的

1
2
ssl_certificate 172.20.10.9.crt;
ssl_certificate_key 172.20.10.9.key;

就是你之前使用openssl生成的证书和私钥。这个要保持一致,而且最好放在同一个目录下。

新建下载页html,配置plist,复制ipa文件和crt文件到指定目录。

上面配置的location就是你的网页资源所有在的目录:

1
2
3
4
location / {
root /usr/local/etc/nginx/doki;
index download.html index.htm;
}

这里我是在nginx目录下新建了一个doki(名字无要求)目录。可以参考一下我的目录结构:

然后我们分别来看一下这几个文件的格式:

html:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http:// www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>DokoDokiLive</title>
</head>
<body>
<h1 style="font-size:40pt">iOS应用OTA安装<h1/>
<h1 style="font-size:40pt">
<a title="iPhone" href="itms-services://?action=download-manifest&url=https://172.20.10.9/DokiDokiLive.plist">点击安装</a>
<h1/>
<a title="iPhone" href="https://172.20.10.9/172.20.10.9.crt">ssl 证书安装</a>
<h1/>
</body>
</html>

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
<?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://172.20.10.9/DokiDokiLive.ipa</string>
</dict>
</array>
<key>metadata</key>
<dict>
<key>title</key>
<string>DokiDoki App download</string>
<key>bundle-version</key>
<string>1.0.0</string>
<key>kind</key>
<string>software</string>
<key>bundle-identifier</key>
<string>com.xxx.xxx</string>
</dict>
</dict>
</array>
</dict>
</plist>

把上面的IP地址和bundle-identifier做相应的替换即可。

成果

reload一下nginx,然后在手机Safari上输入https://172.20.10.9 这个时候可能会提示网站安全,选择查看网站内容,出现下面的界面,说明环境搭建成功。

先安装ssl证书,记得在设置中信任证书(有两处地方需要信任),然后点击安装即可。

结尾

通过搭建本地服务,省去了上传fir的操作,局域网下载ipa速度也比从fir上下载快很多,之前重新安装一个包需要1个多小时的,现在只要十分钟不到就搞定了,所以,遇到问题还是应该多思考,争取能找到更好的解决方案。

后续

原来可以直接把IPA文件通过AirDrop的方式安装到手机上,以上的步骤都可以省略了。不过也是一次好的学习经验。

参考文档:

https://www.jianshu.com/p/75f01a638a07
https://blog.csdn.net/shuaihj/article/details/49999529