专栏首页全栈修仙之路在前端 IPA & APK 还能这样玩

在前端 IPA & APK 还能这样玩

一、背景概述

近期公司为了方便管理内部多个不同版本的测试包,打算在公司内部搭建一个类似蒲公英/fir.im 的安装包管理平台。经过本人的一番搜索在 Github 上发现了 fabu.love 这个项目,基于该项目搭建的应用发布平台,可支持安装包管理、检查更新,灰度发布等功能。此外该项目采用前后端分离的开发方式进行开发,前端技术栈采用 Vue + Element UI,后端技术栈采用 Node.js + Koa,这对于我这个伪全栈来说是一个不错的选择。

fabu.love 这个项目提供 Docker 和源码部署两种方式,作者推荐使用 Docker 方式进行部署,为了快速验证平台效果,本人也是采用 Docker 方式部署。在公司一些小伙伴的配合下,我们完成了第一阶段的测试,得出的结论是基本能满足公司内部的需求。但把结果汇报给 Boss 之后,Boss 又提出了一个需求,若公司目前使用的付费应用分发平台出现异常时,fabu.love 这个平台能否在关键的时刻顶上。对于这个问题,当时我无法给出明确的答复,因为那时我对该项目并没有深入了解且该平台也未经过深度的测试。为了能给出一个较为明确回复,我开始了 fabu.love 项目的源码之旅。

二、项目分析

经过对 fabu.love 源码一番研读之后,发现该项目若要作为第三方平台的“备胎”,提前要先解决以下几个问题:

  • 上传的包存在分发平台所在的服务器上,当并发量高的时候,肯定扛不住;
  • iOS 企业证书版安装时使用的 itms-services 协议对应的 plist 文件(XML 类型)是通过服务端渲染生成的,此外应用下载页使用的是短网址,也是需要在服务端做处理,高并发的时候也会存在问题;
  • 应用下载页面未对下载进行验证并限制下载地址的有效期,无法防止恶意下载。

针对前面的两个问题,通过修改项目的源码,我们都已经解决了,主要的解决方案是等安装包上传成功并成功解析后,把安装包和 iOS 平台对应的 plist 文件同步上传到第三方云存储,比如七牛云。对于第三个问题,我们也初步制定了处理方案。在研读该项目源码的过程中,发现了一个用于解析安装包的插件 —— app-info-parser,接下来我们来介绍一下 app-info-parser。

三、app-info-parser 简介

app-info-parser 是一个解析器用于解析 .ipa.apk 文件。当解析完成后,它会以 JSON 的形式返回 AndroidManifest.xmlInfo.plist 文件中的内容。该解析插件同时支持 Node.js 和浏览器平台。

3.1 安装 app-info-parser

npm install app-info-parser
# or yarn
yarn add app-info-parser

3.2 Node.js 使用示例

const AppInfoParser = require('app-info-parser')
const parser = new AppInfoParser('../packages/test.apk') // or xxx.ipa
  
parser.parse().then(result => {
  console.log('app info ----> ', result)
  console.log('icon base64 ----> ', result.icon)
}).catch(err => {
  console.log('err ----> ', err)
})

除了导入 AppInfoParser 解析器之外,在使用过程中还可以按需导入 IPA 或 APK 安装包的解析器,具体可以参考 app-info-parser 说明文档。

3.3 浏览器使用示例

<input type="file" name="file" id="file" onchange="fileSelect()">
<script src="/dist/app-info-parser.js"></script>
<script>
function fileSelect () {
  const files = document.getElementById('file').files
  const parser = new AppInfoParser(files[0])
  parser.parse().then(result => {
    console.log('app info ----> ', result)
    console.log('icon base64 ----> ', result.icon)
  }).catch(err => {
    console.log('err ----> ', err)
  })
}
</script>

fabu.love 是在后台对安装包进行解析,为了加快用户下载的速度并减少对发布平台的压力,我们还需要把安装包再次上传到第三方云存储,这样的话安装包就需要两次传输。如果在前端解析安装包的话,就可以在成功解析和成功上传之后,再把安装包的信息和对应的下载地址一次性提交到后端。

四、iOS itms-services 协议

itms-service 是 Apple 为 iOS 企业用户提供的无线分发安装方式所使用的协议,使用这种方式发布应用不需要通过 App Store,任何 iOS 设备都可以安装企业用户通过这种方式发布的应用而没有设备数目的限制。itms-service 协议的格式如下:

itms-services://?action=download-manifest&url=http://domain/ios/manifest.plist

基于该协议用户就可以从 Safari 浏览器直接打开上述格式的 itms-services 协议的链接,即可在 iOS 设备上直接安装链接所指向的应用。协议中的 url 参数指向的是一个 plist 文件的 url 链接,该文件是一个 XML 格式的配置文件,以下是 iOS 安装包的 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>{{{ downloadUrl }}}</string>
					<key>md5-size</key>
          <integer>{{{ fileSize }}}</integer>
				</dict>
				 <dict>
         <key>kind</key>
         <string>display-image</string>
         <!-- optional. indicates if icon needs shine effect applied. -->
         <key>needs-shine</key>
         <true/>
         <key>url</key>
         <string>{{{ iconUrl }}}</string>
        </dict>
			</array>
			<key>metadata</key>
			<dict>
				<key>bundle-identifier</key>
				<string>{{{ bundleID }}}</string>
				<key>bundle-version</key>
				<string>{{{ versionStr }}}</string>
				<key>kind</key>
				<string>software</string>
				<key>title</key>
				<string>{{{ appName }}}</string>
			</dict>
		</dict>
	</array>
</dict>
</plist>

在 fabu.love 项目中是通过 mustache 模板引擎来动态生成 iOS 应用所对应的 plist 文件。

五、总结

本文介绍了 fabu.love 应用发布平台和 app-info-parser Apk 和 Ipa 应用包解析插件,除此之外还介绍了 iOS itms-services 协议。对应用发布平台感兴趣的小伙伴,可以参考一下 fabu.love 这个项目,如果遇到问题的话,欢迎一起讨论。

六、参考资源

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • you-dont-know-websocket

    本文阿宝哥将从多个方面入手,全方位带你一起探索 WebSocket 技术。阅读完本文,你将了解以下内容:

    阿宝哥
  • Spring Boot 集成 Spring Security

    Spring Security 是一个能够为基于 Spring 的企业应用系统提供声明式的安全访问控制解决方案的安全框架。它提供了一组可以在 Spring 应用...

    阿宝哥
  • TypeScript keyof 操作符

    TypeScript 允许我们遍历某种类型的属性,并通过 keyof 操作符提取其属性的名称。keyof 操作符是在 TypeScript 2.1 版本引入的,...

    阿宝哥
  • 详解3DTouch集成篇一、准备二、应用添加快捷菜单

    本文主要讲解3DTouch各种场景下的集成,开发主屏幕应用icon上的快捷选项标签(Home Screen Quick Actions),静态设置 UIAppl...

    GuangdongQi
  • 如何做到 Redis 开发规范中的拒绝 bigkey

    代码中的问题,光靠 Code Review 是不够的。Code Review 主要是解决规范问题,当然也能排查出一些 bug。

    业余草
  • Windows多个应用程序共享全局变量,静态变量

    默认情况下exe不同实例使用copy-on-write技术避免共享数据,比如运行了两个exe,最开始它们使用的都是一份虚拟内存页,然后第一个实例修改了全局变量,...

    racaljk
  • ETL是BI(商业智能)的基础,调度是ETL的灵魂

    ETL是数据抽取(Extract)、清洗(Cleaning)、转换(Transform)、装载(Load)的过程

    taskctl官方频道
  • 详解.net中IL语言

    中间语言,又称(IL语言)。充当Clr与.net 平台的中间语言,比如用C#编写程序,编译器首先是把C#代码转译成IL语言,最终由Clr解释执行,下面我们学习下...

    付威
  • 窝窝转型上市 竟是团购市场的利空?

    一波三折,窝窝终于还是上市了。2011年,在千团大战中脱颖而出的窝窝团曾传出上市消息,最终因资本市场整体遇冷不了了之。这一次的成功上市也是历经坎坷:频频被预测上...

    罗超频道
  • 数据分析师必需具备的10种分析思维

    一、逻辑思维 逻辑思维即明白价值链,明白各项数据中的关系; 该方法的关键在于明白其中的关系要求你对这项工作要了解、熟悉,要细致和慎密,要清楚充分性和必要性的关系...

    小莹莹

扫码关注云+社区

领取腾讯云代金券