You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

iOS网页跳转已安装App或App Store:如何检测App是否已安装?

iOS网页端唤起App或跳转App Store的可靠实现

针对你的Expo托管React Native应用网页端需求,iOS Safari出于隐私安全限制,没有提供直接检测App是否安装的API,我们可以通过Universal Links结合页面可见性API优化逻辑,解决现有方案中用户返回浏览器后误跳转App Store的问题。

核心优化思路

放弃依赖blur/focus事件(这类事件触发场景太宽泛,比如切换浏览器标签、弹出系统通知都会触发),改用Page Visibility API(visibilitychange事件)精准判断页面是否因唤起App而被隐藏,同时优化定时器逻辑,避免误触发跳转。

方案一:优先使用Universal Links(推荐,iOS 9+支持)

Universal Links是苹果官方推荐的唤起方式,比自定义URL Scheme更可靠,且不会弹出“无法打开链接”的提示框。

1. Expo项目配置Universal Links

在项目app.json中添加关联域名:

{
  "expo": {
    "ios": {
      "associatedDomains": ["applinks:你的网页域名.com"]
    }
  }
}

同时需在网页域名下配置apple-app-site-association文件(具体配置可参考Expo官方指引)。

2. 网页端实现代码

const openAppOrRedirect = () => {
  const appUniversalLink = 'https://你的网页域名.com/app唤起路径'; // 对应配置的Universal Link
  const appStoreUrl = 'https://apps.apple.com/app/<你的AppID>';
  let timer = null;

  // 监听页面可见性变化
  const handleVisibilityChange = () => {
    if (document.hidden) {
      // 页面被隐藏,说明App已成功唤起,立即清除定时器
      clearTimeout(timer);
      document.removeEventListener('visibilitychange', handleVisibilityChange);
    }
  };

  document.addEventListener('visibilitychange', handleVisibilityChange);

  // 尝试唤起App
  window.location.href = appUniversalLink;

  // 设置定时器,若指定时间内页面未被隐藏,说明App未安装,跳转App Store
  timer = setTimeout(() => {
    document.removeEventListener('visibilitychange', handleVisibilityChange);
    // 仅当页面仍处于可见状态时才跳转
    if (!document.hidden) {
      window.location.href = appStoreUrl;
    }
  }, 1500); // 缩短定时器时长,提升用户体验
};

方案二:优化自定义URL Scheme实现(兼容旧版本iOS)

如果必须使用自定义URL Scheme,可按以下方式优化原有逻辑:

const openAppOrRedirect = () => {
  const appUrlScheme = '你的App自定义Scheme://'; // 如myapp://
  const appStoreUrl = 'https://apps.apple.com/app/<你的AppID>';
  let timer = null;

  const handleVisibilityChange = () => {
    if (document.hidden) {
      clearTimeout(timer);
      document.removeEventListener('visibilitychange', handleVisibilityChange);
    }
  };

  document.addEventListener('visibilitychange', handleVisibilityChange);

  // 尝试唤起App
  window.location.href = appUrlScheme;

  timer = setTimeout(() => {
    document.removeEventListener('visibilitychange', handleVisibilityChange);
    if (!document.hidden) {
      window.location.href = appStoreUrl;
    }
  }, 1500);
};

关键改进点

  1. 用visibilitychange替代blur/focus:只有页面真正被隐藏(比如切换到App)时才触发,避免了切换标签、弹出通知等场景的误判。
  2. 定时器触发前校验页面状态:即使用户返回浏览器,只要定时器触发时页面是可见的,才会跳转App Store;若App已成功唤起,定时器会被提前清除,不会重复跳转。
  3. 缩短定时器时长:从2500ms调整为1500ms,减少用户等待时间,同时保证iOS有足够时间尝试唤起App。

补充说明

  • Android端你已使用intent://方案,可保持不变,网页端可通过判断用户Agent区分平台分别处理。
  • 受iOS隐私限制,无法完全消除定时器,但通过上述优化可将误跳转概率降到最低。

内容的提问来源于stack exchange,提问作者HSP

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 00:54:56