h5网页唤醒app的方案

2,963 阅读4分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第 5 天,点击查看活动详情


背景

我支撑的业务线主要是做广告引流业务的,经常会需要将用户从 h5 落地页内引流到 app 内部,这种行为在广告营销里对用户增长十分重要。关于这种场景的实现跟我们安卓和 ios 开发也讨论了一下,整理了一下常见的解决方案。

自实现

URL Scheme

URL Scheme这种方式较为主流,各平台兼容性也很好,URL Scheme一般由协议名、路径、参数组成。我们可以从安卓和 ios 开发那里得到对应 app 的 scheme。URL Scheme其实就是一个 url,我们通过这种方式唤醒 app 的话和在 h5 内打开一个 url 是一样的,location.hrefa标签iframe的方式都可以。

[协议名]://[路径]?[参数]
class openApp {
  constructor(opt) {
    this.URLScheme = opt.URLScheme;
    this.downLoadUrl = opt.downLoadUrl;
  }
  open() {
    window.location.href = this.URLScheme;
  }
}

我们还需要在用户未下载时打开 app 的下载页,而这种方式我们获取不到用户是否真的打开了 app,但是我们可以发现,如果打开 app 成功的话当前页面就被隐藏了,所以我们可以通过监听页面可见属性,来判断有没有唤醒 app。而唤醒 app 也不是实时的,会有一个启动过程,所以需要大概 3s 后跳转到下载页面。

class openApp {
  constructor(opt) {
    this.URLScheme = opt.URLScheme;
    this.downLoadUrl = opt.downLoadUrl;
    this.timer = null;
  }
  open() {
    this.watchVisibility();
    window.location.href = this.URLScheme;
    this.timer = setTimeout(() => {
      window.location.href = this.downLoadUrl;
    }, 3000);
    return;
  }
  watchVisibility() {
    document.addEventListener("visibilitychange", () => {
      console.log(document.visibilityState);
      if (document.visibilityState == "hidden") {
        this.timer && clearTimeout(this.timer);
      }
    });
  }
}

Universal Link(ios)、App Link(安卓) 和 Intent(安卓)

Universal Link是 ios 在 ios9 之后推出的一种唤醒 app 的方式,它相比URL Scheme的好处在于,打开 app 时不会有二次弹框,并且它本身就是一个 url 链接,打开 app 失败的话会自动打开这个 url 网页。但是它存在一个问题就是必须要跨域访问才会唤醒 app,比如,落地页地址是a.com,如果 Universal Link 的域名地址也是a.com的话那将会直接打开页面,而不是唤醒 app。

App Link则是安卓在安卓 6 之后推出的一种唤醒 app 的方式,但是咨询安卓开发的朋友说这种方式在国内很少使用了,兼容较差,一般都使用第三方或者URL Scheme方式,故该方式不做考虑。

intent则是针对谷歌浏览器唤起安卓 app 的一种方式,唤醒失败会跳到谷歌商店,国内也受限,不予考虑。

class openApp {
  constructor(opt) {
    this.URLScheme = opt.URLScheme;
    this.downLoadUrl = opt.downLoadUrl;
    this.UniversalLink = opt.UniversalLink;
    this.ua = navigator.userAgent.toLowerCase();
    this.timer = null;
  }
  //...
  open() {
    if (this.isAndroid()) {
      this.watchVisibility();
      window.location.href = this.URLScheme;
      this.timer = setTimeout(() => {
        window.location.href = this.downLoadUrl;
      }, 3000);
      return;
    }
    if (this.isIOS()) {
      if (this.UniversalLink) {
        window.location.href = this.UniversalLink;
        return;
      }
      this.watchVisibility();
      window.location.href = this.URLScheme;
      this.timer = setTimeout(() => {
        window.location.href = this.downLoadUrl;
      }, 3000);
      return;
    }
  }
}

问题

目前对客营销最大的平台还是微信,但是在微信下,以上几种唤醒方式都或多或少有问题,要不完全被屏蔽,要不就是出现风险提示,想在微信生态下唤醒成功需要迎合微信做改变,常见的方式是 app 上架应用宝,生成一个应用宝的链接或者通过微信开放标签去实现,前者只适用于安卓平台,后者则需要搭建公众号环境以及绑定开放平台。此外,还有一种认可度较高的方案就是:引导用户用浏览器打开页面。“既然你限制这么多,操作起来还麻烦,我就直接不用你了,用别的浏览器访问”。类似微信这样的浏览器还有 qq 浏览器,微博自带的浏览器都需要这样处理。

另一个问题是在部分手机浏览器下location.href唤醒 app 的方式不生效,需要使用iframe的方式,还可以通过判断不同的浏览器使用不同的打开链接方式,类似的浏览器包括不限于:华为自带浏览器。

调用三方

callapp-lib是社区开源的一个 h5 唤起 app 的解决方案,能够满足大部分唤端场景,支持 npm 和 cdn 的方式引入。常见的唤醒方式都支持当参数传入,详情可以参考官方文档github.com/suanmei/cal…

const opt = {
  scheme: {
    protocol: "",
  },
  appstore: "",
  yingyongbao: "",
  fallback: "",
};
const lib = new CallApp(opt);
lib.open({
  path: "profile",
});

结尾

如果你觉得此文有帮助的话,可以帮忙点个赞,鼓励一下作者哦~~~。

自实现唤醒代码查看 github:https://github.com/yuwuwu/blog-code/

参考资料

《闲鱼唤端的背后》