场景
公司想通过落地页做以下两种事情:
- 如果用户安装了公司APP,直接打开APP,并跳转对应页面。
- 如果用户未安装公司APP,跳转到APP下载页面。
分析
分析上面场景,我们找到两个角色,H5(落地页)、APP,但是明显H5不能直接与APP交互,进一步分析,H5需要容器,比如浏览器或别的应用,APP需要操作系统承载或APP的URL。
于是,找到了四个重要的角色:H5、容器、操作系统、APP。四个角色的交互是:H5通过某种协议告诉容器要唤起APP,容器或拦截或不拦截该协议,容器把意图传递给操作系统,操作系统判断本地是否有目标APP,有就打开,无安装时打开指定页面或什么都不做。
以上描述较模糊,以下针对不同系统,不同协议做具体说明。
系统及协议
1. iOS、安卓之URL Scheme协议
该协议是两个系统下唯一通用的协议,协议格式:
[scheme:][//authority][path][?query][#fragment]
理解该格式,同http协议便可。scheme->http,authority(APP名)->域名。例如可以在页面的a标签里使用该协议
<a href="scheme://com.baidu/search?word=abc">唤起百度APP</a>
当用户点击该标签,就会唤起百度APP。
1.1 协议问题
系统未安装APP时,iOS会提示页面不存在,安卓下什么都不做。而且当前H5页面不知道有没有唤起该APP。
1.2 问题解决
通常的解决方案是,执行唤起动作两秒后检查页面是否隐藏,如果隐藏了,就认为唤起了APP,如果没有隐藏,就执行自己想要的后续操作,比如跳转到下载页面。该方案不够完美,主要是该协议不够完美。
2. iOS之Universal Link协议
该协议就是一个标准的URL。本地有APP就唤起APP,没有APP就打开该URL。如此简单。但是,如何让该协议生效呢,看苹果官方文档吧:developer.apple.com/ios/univers…
3. 安卓之Intent协议
协议格式:
intent:
HOST/URI-path // 同URL格式一样,由APP去解析
#Intent;
package=[包名];
scheme=[];
S.browser_fallback_url=[唤起APP失败后打开的URL]
end;
例如
<a href="intent://www.baidu.com?word=a#Intent;package=com.baidu;scheme=baidu;S.browser_fallback_url=https%3A%2F%2Fwww.baidu.com%2F">唤起百度APP</a>
点击该链接会按以下逻辑执行,如果有APP就唤起APP,没有就打开系统默认商店,如果没打开应用商店,就打开S.browser_fallback_url对应的URL。
4. 总结
以上协议有几个特点:包名,路径,参数。 其中包名由端上同学提供,路径及参数需同端上同学一起约定,毕竟当唤起APP之后,需要APP做出相应的动作,这些动作的执行主要靠路径及参数完成。
以上是常用的唤起APP协议。既然是协议就有协议的实现者,通常协议的实现者是浏览器,当然,这里少不了系统的支持。浏览器有很多,我们这些使用方在使用这些协议的时候,具体的表现形式是不可控的。
浏览器本质上也是APP,那么带有webview的APP也可以认为是特殊的浏览器,比如微信。那么当微信打开我们的页面时,会发生什么呢,以上所有的协议,均被微信做了限制。也就是说微信不支持以上所有的协议。微信有自己的唤起APP的协议,称之为开放标签,移步:developers.weixin.qq.com/doc/oplatfo… 。其实当你实现了微信开发标签,微信打开你的APP时,执行的依然是系统支持的APP唤起协议,只不过微信强行你在他的平台上留下产品信息。
5. 随想
如果你家公司有两款APP,a和b,你们也可以让自己APP实现一种协议,但是意义不大,无非是可以在本地没有对应APP时做出更好的交互。但是最终还是要使用系统支持的协议才能唤起指定APP,除非你家公司有自己的系统。如果你家公司有自家系统,也可以完全实现一种全新的协议,来供自己系统上第三方APP使用,以便约束他们的行为。但是可以为自家APP开后门,做到更流畅更简洁的交互。