一.需求
- 大批量的app内测。
- 针对app审核难过包,可以考虑企业签名暂时代替appstore发布(网上资料说是有封开发者账号的风险)。
二.原理
- OTA:
iOS4
新加的一项技术,可以让开发者脱离AppStore,从指定的服务器下载安装应用。 - 以
https://itms-services://?action=download-manifest&url=https://192.168.1.xxx/manifest.plist
开头的链接,Safari会自动去读取manifest.plist
中的信息,进行下载,安装等操作。
三.准备工作
-
三种开发者账号:
- 个人账号:
99$
/appstore上架
/设备上限100
- 公司账号:
99$
/appstore上架
/设备上限100
- 企业账号:
299$
/不能appstore上架
/不限制设备(没有验证过)
- 个人账号:
-
打包模式:
-
App Store Deployment
:需要添加UUID
/上架appstore
-
Ad Hoc Deployment
:需要添加UUID
/内部测试
/distribution证书
-
Enterprise Deployment
:不需要添加UUID
/企业内部应用
/企业证书
-
Development Deployment
:需要添加UUID
/开发调试
/developer证书
-
-
ipa包:
- 如果只是方便内部测试的分发,用
个人/公司账号
/发布到Ad Hoc Deployment/Development Deployment
打出来的ipa
- 如果是企业内部应用/绕开苹果审核而发布的应用,就必须用
企业账号
/发布到Enterprise Deployment
打出来的ipa
- 如果只是方便内部测试的分发,用
manifest.plist
https协议服务器(
iOS7.1以前的版本支持http协议
)
四.实现
背景:在本机
搭建https
服务器的企业账号
签名的应用分发
-
ipa包
- 申请企业账号(步骤省略)
- 发布到
Enterprise Deployment
打包(步骤省略)
-
搭建本机服务器
Mac OS X
自带Apache
服务,其站点默认根目录是/Library/WebServer/Documents/
;
默认根目录可以修改,打开/etc/apache2/httpd.conf
,搜索DocumentRoot:/Library/WebServer/Documents
换成自定义的路径:/*/Library/WebServer/Documents 换成自定义的路径*/ DocumentRoot "/Library/WebServer/Documents"
# Possible values for the Options directive are "None", "All", .省略 .省略 .省略 # or any combination of: Require all granted - 启动
Apache
:sudo apachectl start
- 测试
Apache
:safari
输入http://127.0.0.1/
,如果出现It Works!
,则成功启动
- 启动
-
开启https服务
- 生成ssl证书
- 进入相应文件夹
cd /etc/apache2/
- 生成私钥:
sudo openssl genrsa -des3 -out app.key 1024
- 生成签署申请:
sudo openssl req -new -key app.key -out app.csr
- 生成服务器私钥:
sudo openssl rsa -in app.key -out server.key
- 生成给网站服务器签署的证书:
sudo openssl req -new -x509 -days 3650 -key server.key -out server.crt
- 终端命令:
skylinedeMacBook-Air:apache2 skyline$ cd /etc/apache2/ skylinedeMacBook-Air:apache2 skyline$ sudo openssl genrsa -des3 -out app.key 1024 Generating RSA private key, 1024 bit long modulus ..........++++++ ...............++++++ e is 65537 (0x10001) Enter pass phrase for app.key://输入密码 Verifying - Enter pass phrase for app.key://验证密码 skylinedeMacBook-Air:apache2 skyline$ sudo openssl req -new -key app.key -out app.csr Enter pass phrase for app.key://输入密码(同上) 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//中国简称CN State or Province Name (full name) []:GD//省 Locality Name (eg, city) []:SZ//市 Organization Name (eg, company) []:company//组织/公司 Organizational Unit Name (eg, section) []:company.ltd//组织 Common Name (eg, fully qualified host name) []:192.168.1.1xx//本机IP Email Address []:[email protected]//邮箱 Please enter the following 'extra' attributes to be sent with your certificate request A challenge password []:123456 skylinedeMacBook-Air:apache2 skyline$ sudo openssl rsa -in app.key -out server.key Enter pass phrase for app.key: writing RSA key skylinedeMacBook-Air:apache2 skyline$ sudo openssl req -new -x509 -days 3650 -key server.key - out server.crt 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) []:GD//省 Locality Name (eg, city) []:SZ//市 Organization Name (eg, company) []:company//组织 Organizational Unit Name (eg, section) []:company.lct组织 Common Name (eg, fully qualified host name) []:192.168.1.1xx//本机IP Email Address []:[email protected]//邮箱 skylinedeMacBook-Air:apache2 skyline$ sudo apachectl configtest Syntax OK skylinedeMacBook-Air:apache2 skyline$ sudo apachectl
- 进入相应文件夹
- 生成ssl证书
-
开启ssl功能
- 文本打开
/etc/apache2/httpd.conf
,去掉下面五行的#
(/etc/apache2/xxx
等同于/private/etc/apache2/xxx
):#LoadModule ssl_module libexec/apache2/mod_ssl.so #Include /etc/apache2/extra/httpd-ssl.conf #Include /etc/apache2/extra/httpd-vhosts.conf #LoadModule socache_shmcb_module libexec/apache2/mod_socache_shmcb.so #ServerName www.example.com:80
- 文本打开
/etc/apache2/extra/httpd-ssl.conf
,去掉下面两行的#
(server.crt
/server.key
的路径可能不在httpd-ssl.conf
默认的路径/etc/apache2/ssl/
下,要么修改默认路径,要么server.crt
/server.key
拷贝到默认路径下):#SSLCertificateFile "/etc/apache2/server.crt" #SSLCertificateKeyFile "/etc/apache2/server.key
- 文本打开
/etc/apache2/extra/httpd-vhosts.conf
,在末尾添加:SSLEngine on SSLCipherSuite ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP:+eNULL SSLCertificateFile /private/etc/apache2/server.crt //注意与httpd-ssl.conf的路径统一 SSLCertificateKeyFile /private/etc/apache2/server.key //注意与httpd-ssl.conf的路径统一 ServerName 192.168.1.1xx //本机IP DocumentRoot "/Library/WebServer/Documents" //本地站点默认目录 ``` - 测试/重启apache
sudo apachectl configtest sudo apachectl restart
- 文本打开
-
编辑manifest.plist文件
- 模版如下,直接在上边更改成应用对应参数
items assets kind software-package url https://192.168.1.xxx/tlsc.ipa kind display-image url https://192.168.1.xxx/AppIcon57x57.png kind full-size-image url https://192.168.1.xxx/AppIcon512x512.png metadata bundle-identifier com.tlsc.shacheng bundle-version 1.1.1 kind software releaseNotes 1.1.1版本发布 title 应用分发测试app
- 模版如下,直接在上边更改成应用对应参数
-
站点根目录
/Library/WebServer/Documents
需要的文件 -
测试验证
- safari输入
https://192.168.1.xxx
,结果如下:
- 先安装ssl证书
- 再安装app
- safari输入
五.问题及解决
- 无法连接到192.168.1.xxx,可能原因如下:
-
index.html
中获取manifest.plist
的地址不对 -
manifest.plist
中设置的ipa
的地址不对 - 没有下载SSL证书,下载安装(
设置
->通用
->描述文件与设备管理
)查看 - 信任根证书,
设置
->通用
->关于手机
->证书信任设置
->信任证书
-
- 无法安装应用,可能原因如下:
-
ipa
本身存在问题,无法安装到手机上,可先用越狱手机或itools之类的软件测试是否能正确安装 -
manifest.plist
里面的bundleID
与ipa
的bundleID
不一致 - 手机储蓄空间不足
-
- 修改了相关的地方,问题还是解决不了:
- 浏览器会有缓存,多退出几次,或者直接把修改的文件改名,让浏览器重新指向新命名的文件。
六.WKwebView访问https不成功
- https服务没开,按照
第四条
,第3点
,开启https服务 - https服务开了:
- 在
info.plist
文件中设置Allow Arbitrary Loads in Web Content
置为YES
(或者NSAllowsArbitraryLoads=YES
) - 实现
WKWebView
的代理WKNavigationDelegate
方法:
- 在
- (void)webView:(WKWebView *)webView didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential * _Nullable credential))completionHandler
{
if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust])
{
NSURLCredential *card = [[NSURLCredential alloc]initWithTrust:challenge.protectionSpace.serverTrust]; completionHandler(NSURLSessionAuthChallengeUseCredential,card);
}
}