ios实现ipa下载的大概逻辑是:
访问plist文件,plist文件里面有ipa包的完整下载地址。访问plist文件记得加前缀 itms-services://?action=download-manifest&url=
###.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.0">
<dict>
<key>items</key>
<array>
<dict>
<key>assets</key>
<array>
<dict>
<key>kind</key>
<string>software-package</string>
<key>url</key>
#完整的ipa文件地址
<string>https://xxx.xxx.xxx.xxx:80/web/xxx.ipa</string>
</dict>
</array>
<key>metadata</key>
<dict>
<key>bundle-identifier</key>
#开发者账号,也就是包名
<string>包名</string>
<key>bundle-version</key>
<string>版本号</string>
<key>kind</key>
<string>software</string>
<key>title</key>
<string>系统名称</string>
</dict>
</dict>
</array>
</dict>
</plist>
方式1:html+plist
生成plist文件,生成html,在html里面通过a标签访问plist文件,plist文件里面有安装包的信息。这里网上很多教程,不细说。
方式2:接口文件流返回相关文件
步骤
1、接口生成plist返回给前端
2、接口返回ipa给前端
坑一:传递参数的方式
- 通过接口返回plist文件。
#错误的接口方式
itms-services://?action=download-manifest&url=https://xxx.xxx.xxx:80/web/install?A=XX&B=XX
这种就是通过@RequestParam获取参数
#正确接口
itms-services://?action=download-manifest&url=https://xxx.xxx.xxx:80/web/install/{A}/{B}
这种是通过@PathVariable
此接口返回plist文件,如果不是@PathVariable,而是@RequestParam这种,通过item-services无法发送对plist的请求。效果就是不用@PathVariable浏览器拉不起来安装弹窗。
- 动态返回plist文件时,controller内重点代码
#这个不需要设置
response.setHeader(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + name + "\"");
#媒体类型设置时xml格式的
response.setHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_XML_VALUE);
#告知文件大小,影响浏览器下载进度条,没有大小没有进度条
response.setContentLength(xmlStr.getBytes().length);
坑二:&符问题
.plist 的xml文件中,如果访问ipa文件的地址带有&符,这里得使用
&符得使用 &
坑三:编码转义问题
访问路径404、415问题
标准的Base64编码会出现+、/和=,所有不适合把Base64编码后的字符串放到URL中,如果请求的是接口,路径中又有/,可能会出现接口访问404问题,建议把/转换成_,后端接收后再将下划线转成/
前端:/转成_
后端:_转成/
如果不转,接口访问报错415,不支持的媒体类型