通用技术 从零开始 OTA,无线安装 ipa

joyyang · 2019年05月15日 · 最后由 lulin 回复于 2019年11月19日 · 416 次阅读
本帖已被设为精华帖!

概述

一、OTA 是什么?

OTA 就是Over-the-Air,是苹果为了使开发者能够通过无线方式分发自己内部的应用而提供的一种技术。

通过 OTA 的方式安装,开发者只需在移动设备上访问指定的 Url 即可进行下载安装,不必再依赖数据线。

二、架设 OTA 需要什么?

需要 备注
Web 服务器 可以直接使用 Mac 上的 Apache 或者下载配置 Nginx
SSL 证书 用来开启 HTTPS 服务
HTTPS 服务 根据苹果官方文档,对于 iOS 7.1 及以系统必须使用 HTTPS
HTML 页面 用来下载安装包的页面
IPA 有个人开发者或者企业签名的 IPA 包
manifest.plist IPA 对应的清单文件
icon 57*57 和 512*512 的图片

部署

一、Web 服务器部署

Mac 自带 Apache(也可以使用 nginx),我们可以直接进行用httpd -v查看 apache 的版本号

$ httpd -v
Server version: Apache/2.4.34 (Unix)
Server built:   Feb 22 2019 19:30:04

Apache 的常用命令:

  • 启动:sudo apachectl start
  • 停止:sudo apachectl stop
  • 重启:sudo apachectl restart

启动 Apache 后在浏览器中输入http://localhost或者http://127.0.0.1,看到 “It Works” 页面即开启成功


Mac 上 Apache 的文件目录默认在/Library/WebServer/Documents,可以通过/etc/apache2/httpd.conf进行修改

二、获得 SSL 签名证书

这里我们使用自签名的方式,有条件的话可以付费选择苹果认证的签名

  • 创建存储证书的路径
$ cd /private/etc/apache2/
$ sudo mkdir ssl
$ cd ssl
  • 创建主机秘钥
$ sudo openssl genrsa -out ip211.key 2048
Generating RSA private key, 2048 bit long modulus
...............................................................................................................+++
.......................................................+++
e is 65537 (0x10001)
  • 创建签署申请
$ sudo openssl req -new -key ip211.key -out ip211.csr

注意 Comon Name 处一定要填写完整的域名或者 IP 地址,其他可以随意填写或留空

You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) []:cn
State or Province Name (full name) []:
Locality Name (eg, city) []:
Organization Name (eg, company) []:
Organizational Unit Name (eg, section) []:
Common Name (eg, fully qualified host name) []:10.6.60.211
Email Address []:

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
  • 创建 SSL 证书
    -days 参数后面是证书有效期,根据自己需求更改
$ sudo openssl x509 -req -days 3650 -in ip211.csr -signkey ip211.key -out ip211.crt

Signature ok
subject=/C=cn/CN=10.6.60.211
Getting Private key
  • 移除秘钥的密码
$ sudo openssl rsa -in ip211.key -out ip211-nopass.key

writing RSA key

操作完毕后我们应该有以下几个文件

$ ls -l
total 32
-rw-r--r--  1 root  wheel  1679 May  9 17:01 ip211-nopass.key
-rw-r--r--  1 root  wheel  1017 May  9 16:44 ip211.crt
-rw-r--r--  1 root  wheel   911 May  9 16:37 ip211.csr
-rw-r--r--  1 root  wheel  1679 May  9 16:35 ip211.key

三、配置 HTTPS 服务

1 备份要修改的文件

$ sudo cp /private/etc/apache2/httpd.conf /private/etc/apache2/httpd.conf.bak  
$ sudo cp /private/etc/apache2/extra/httpd-ssl.conf /private/etc/apache2/extra/httpd-ssl.conf.bak  
$ sudo cp /private/etc/apache2/mime.types /private/etc/apache2/mime.types.bak  

2 修改配置文件/private/etc/apache2/httpd.conf (只读文件,请用管理员权限打开以便修改,如:sudo vim /private/etc/apache2/httpd.conf)

(1) 加载 Apache 中与 HTTPS 相关的模块,去掉以下两个模块的注释

LoadModule socache_shmcb_module libexec/apache2/mod_socache_shmcb.so
LoadModule ssl_module libexec/apache2/mod_ssl.so

(2) 加载 Apache 中与 HTTPS 相关的配置,去掉以下配置的注释

Include /private/etc/apache2/extra/httpd-ssl.conf

3 修改配置文件/private/etc/apache2/extra/httpd-ssl.conf (只读文件,请用管理员权限打开以便修改,同上)
修改以下三处:
(1) ServerName,主机名,改为本机的 IP

ServerName 10.6.60.211

(2) SSLCertificateFile,证书路径,改为 SSL 证书存放路径

SSLCertificateFile "/private/etc/apache2/ssl/ip211.crt"

(3) SSLCertificateKeyFile,秘钥路径,改为 SSL 未加密秘钥存放路径

SSLCertificateKeyFile "/private/etc/apache2/ssl/ip211-nopass.key"

4 设定服务器 MME 类型
根据苹果官方文档,需要将 ipa 和 plist 加入服务器的 MME 类型

修改/private/etc/apache2/mime.types,加入以下两条

application/octet-stream ipa
text/xml plist

5 检测 Apache 配置文件并重启 Apache

$ sudo apachectl -t

可能会报错

AH00557: httpd: apr_sockaddr_info_get() failed for bogon
AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 127.0.0.1. Set the 'ServerName' directive globally to suppress this message
Syntax OK

可以修改/private/etc/apache2/httpd.conf,将ServerName的注释取消,再次检测

$ sudo apachectl -t
Syntax OK

其他报错自行查找解决,无报错后重启 Apache

sudo apachectl restart

在浏览器输入https://即可访问

四、准备 ipa 和对应的 manifest.plist

1 在 Web 服务器的文件目录下创建对应的文件夹

进入 Apache Web 服务器的文件根目录/Library/WebServer/Documents,创建包的存放路径,icon 存放路径,SSL 证书存放路径

$ sudo mkdir testapp
$ cd testapp
$ sudo mkdir ipa
$ sudo mkdir icon
$ sudo mkdir ssl
$ sudo mkdir plist
  • 生成的 ipa 放入 testapp 文件夹下
  • 57/*57 和 512/*512 的 icon 放入 icon 文件夹下
  • manifest.plist 放入 plist 文件夹下
  • 生成的 crt 文件放入 ssl 文件夹下
sudo cp /private/etc/apache2/ssl/ip211.crt /Library/WebServer/Documents/testapp/ssl/ip211.crt

2 生成 manifest.plist 文件_(也可以跳过此步奏直接修改现成 manifest.list 模版)

  • Mac 上打包的步骤不再详述,在 Archive 时,将Include manifest for over-the-air installation选项勾上
  • 依次填入内容

Name:【包的显示名字】
App URL:【https://主机地址/testapp/ipa/xxx.ipa】
Display Image URL:【https://主机地址/testapp/icon/52.png】
Full Size Image URL:【https://主机地址/testapp/icon/512.png】
  • 最后在生成的 ipa 目录下会同时生成一个 manifest.plist 文件 3 修改 manifest.plist 模版
    manifest.plist 如下(【】内是需要修改的内容,正式内容不包括【】)
<?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://主机地址/testapp/ipa/xxx.ipa】</string>
                </dict>
                <dict>
                    <key>kind</key>
                    <string>display-image</string>
                    <key>url</key>
                    <string>【https://主机地址/testapp/icon/52.png】</string>
                </dict>
                <dict>
                    <key>kind</key>
                    <string>full-size-image</string>
                    <key>url</key>
                    <string>【https://主机地址/testapp/icon/512.png】</string>
                </dict>
            </array>
            <key>metadata</key>
            <dict>
                <key>bundle-identifier</key>
                <string>【Bundle ID】</string>
                <key>bundle-version</key>
                <string>【版本号】</string>
                <key>kind</key>
                <string>software</string>
                <key>title</key>
                <string>【包的显示名字】</string>
            </dict>
        </dict>
    </array>
</dict>
</plist>

需要修改和确认的字段说明

字段 说明
software-package 应用 (.ipa) 文件的完全限定 HTTPS URL
display-image 57 x 57 像素的 PNG 图像,在下载和安装过程中显示。指定图像的完全限定 URL
full-size-image 512 x 512 像素的 PNG 图像,表示 iTunes 中相应的应用
bundle-identifier 应用的包标识符,com.xx.xxx
bundle-version 应用的包版本,0.1.0
title 下载和安装过程中显示的应用的名称

修改完毕后,将 manifest.plist 放入/Library/WebServer/Documents/testapp/plist目录下

五、制作下载所用 Web 页面

OTA 是通过 WebKit 解析链接中的itms-services://来实现的,因此我们需要做超链接

<a href="itms-services://?action=download-manifest&url=【https://example.com/manifest.plist】">Install App</a>

另外需要在手机上安装签名证书,因此需要给证书也做一个超链,完整 HTML 如下:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" mime-types="text/plain">
            <title></title>
            </head>
    <body>
        <a style="display:block" href="itms-services://?action=download-manifest&url=【https://主机地址/testapp/plist/manifest.plist】">下载ipa</a>
        <a style="display:block" href="【https://主机地址/testapp/ssl/ip211.crt】">下载证书</a>
    </body>
</html>

存为index.html,放入/Library/WebServer/Documents/testapp/

六、下载安装

在 iPhone 上用 Sarfri 浏览器,访问https://主机地址/testapp/即可看到


点击下载证书,下载安装配置文件

设置-通用-描述文件与设备管理中,选择已下载的配置文件,进行安装


安装时会提示:只有在 “证书信任设置” 中启用,网站才会信任此证书。


这是在 iOS 10 中,苹果加入的认证,因此还需在设置-通用-关于本机-证书信任设置中将完全信任打开


再返回 Sarfri 浏览器,点击 “下载 ipa”,即可下载安装

共收到 16 条回复 时间 点赞
joyyang 从零开始在 Jenkins 上显示打包二维码 中提及了此贴 05月15日 06:51

之前试过,发现非付费的 https 正式不好使。选用的方案是正式 https 正式, 👍

思寒_seveniruby 将本帖设为了精华贴 05月15日 15:20

向大佬学习把一个贼简单的东西说复杂~

很久以前想帮公司做一个内网分发,做得不是很好,应该还能跑
https://github.com/skytoup/AppServer

感觉觉得没啥用处,不过感谢分享。乐于分享的精神还是值得鼓励

py 简易局域网文件分享,干掉一切繁琐

python -m http.server
默认端口:8000,默认风险当前命令行文件夹下的文件

跟蒲公英分发有什么优势?

yiwang 回复

1.内网传输比较方便
2.研发期间不适合传输到外网的应用

Benjamin 回复

ipa 的安装需要 HTTPS

e4rljia 回复

目的是想方便零基础的人按照步骤一步一步也能部署

joyyang 回复

查了一下可以倒入 ssl

import BaseHTTPServer, SimpleHTTPServer
import ssl

web_server = BaseHTTPServer.HTTPServer(('localhost', 8443), SimpleHTTPServer.SimpleHTTPRequestHandler)
web_server.socket = ssl.wrap_socket (web_server.socket, 
                                     server_side=True,
                                     certfile="xxx.crt",
                                     keyfile="xxx.key")
web_server.serve_forever()
joyyang 回复

说明下,plist 的链接必须是 https 的但是 plist 里的 ipa 可以不是 https 的。

e4rljia 回复

没有尝试过用 HTTP 的,根据苹果官方文档是要用 HTTPS 的
官方文档
URL:应用 (.ipa) 文件的完全限定 HTTPS URL

仅楼主可见

用内网分发太麻烦了,直接上河马网站上注册个账号,然后丢 ipa 包上去,就可以直接分发测试了,超级简单,网址:https://hema.im

和 testflight 有什么区别

married577 回复

TF 有点重还是

谢谢分享,楼上的几位只是单独的看 OTA 这件事,觉得可能有更好的代替品,但是掌握这个技巧之后,再稍微拓展一下,是可以应对其他场景的。如果只是做简单的内网分发,的确有别的代替工具,但是你分发之前是不是需要先把安装包从服务器下载下来,传到蒲公英或者河马上 然后再把链接发到工具群里?而我用 Jenkijns+ python+ Flask + 钉钉机器人 做了一个 打包完成后自动上传到 web 服务器,然后生成下载二维码,通过钉钉机器人把二维码发到工作群里的工具,分发过程全程自动化,只需要构建 Jenkijns 上的打包 job 即可。但之前只有 Android 可以发下载二维码,iOS 只能发一个下载链接在群里,就是因为不会弄 OTA,也是弄了很久才搞明白。 所以我觉得楼主的分享还是很有意义的。

simple [精彩盘点] TesterHome 社区 2019 年 度精华帖 中提及了此贴 12月24日 15:00
simple [精彩盘点] TesterHome 社区 2019 年 度精华帖 中提及了此贴 12月24日 15:00
需要 登录 后方可回复, 如果你还没有账号请点击这里 注册