iOS 13已安装应用时Deep Link无法正常跳转问题
解决iOS 13下Deep Link同时唤起App和跳转App Store的问题
这个坑我之前帮开发者排查过!iOS 13之后苹果对HTTP/HTTPS链接唤起App的逻辑做了不少调整,才会出现你遇到的这种「双唤起」情况,iOS 12及以下没触发是因为旧系统的处理逻辑更宽松。下面给你拆解原因和对应的解决方案:
核心原因分析
- iOS 13开始,系统对未配置Universal Links的HTTP/HTTPS链接,在尝试用URL Scheme唤起App后,会默认 fallback 到打开Safari页面;如果你的网页里有
apple-itunes-app元标签,或者服务器端有跳App Store的重定向规则,Safari就会触发App Store跳转。 - 另一种可能是你的URL Scheme唤起逻辑没有阻止网页的默认行为,导致系统同时执行了Scheme唤起和网页跳转。
具体解决方案
1. 优先迁移到Universal Links(推荐)
苹果在iOS 9之后就主推Universal Links,它能完美避免这种冲突——点击HTTPS链接时,系统会先检查是否安装了关联的App,有就直接唤起App并传递参数,没有才打开网页。配置步骤如下:
- 在Apple Developer后台,给你的App开启Associated Domains权限,添加
applinks:abc.in(替换成你的实际域名)。 - 在你的App的
Info.plist里添加NSAppTransportSecurity的例外(如果是HTTPS域名可跳过),并确保Associated Domains配置正确。 - 在服务器的根目录(或
.well-known目录)上传apple-app-site-association文件,内容示例:
{ "applinks": { "apps": [], "details": [ { "appID": "你的团队ID.你的App包名", "paths": [ "/abc/verify/*" ] } ] } }
这里的paths指定哪些路径需要唤起你的App,和你邮件里的链接路径对应即可。
2. 修复现有URL Scheme的网页唤起逻辑
如果暂时不想切换到Universal Links,可以修改网页端的唤起代码,确保iOS 13下只触发App唤起:
- 用JavaScript阻止页面的默认跳转,优先唤起App,示例代码:
document.addEventListener('DOMContentLoaded', function() { // 获取链接里的stud_id参数 const studId = new URLSearchParams(window.location.search).get('stud_id'); // 替换成你的App的URL Scheme const appSchemeUrl = '你定义的Scheme://verify?stud_id=' + studId; // 尝试唤起App window.location.href = appSchemeUrl; // 可选:如果1秒后没唤起成功,跳转网页版确认页(别跳App Store) setTimeout(function() { window.location.href = '/web-verify?stud_id=' + studId; }, 1000); });
- 检查服务器端配置,确保
http://abc.in/abc/verify/没有重定向到App Store的规则,比如.htaccess里的跳转指令或者后端的重写逻辑。
3. 排查网页中的App Store触发因素
打开http://abc.in/abc/verify/页面,检查是否有以下内容:
<meta name="apple-itunes-app" content="app-id=你的AppID">:这个标签会在Safari显示智能横幅,若代码里有自动点击横幅的逻辑,就会跳App Store。如果不需要可以移除,或者调整横幅的显示逻辑。- 自动跳转到App Store的JavaScript代码:比如
window.location.href = 'https://apps.apple.com/cn/app/xxx/idxxxx',这类代码会在唤起App后被执行,导致双跳转。
4. 检查App的Info.plist配置
确认你的App的URL Scheme配置正确:
- 在
CFBundleURLTypes->CFBundleURLSchemes里,确保你的Scheme拼写正确,没有重复。 - iOS 13之后,虽然自己唤起自己不需要,但可以尝试在
LSApplicationQueriesSchemes里添加你的Scheme,避免系统拦截。
测试小贴士
- 一定要用真机测试,模拟器的Deep Link行为和真机有差异。
- 测试时确保App已经安装在设备上,未安装的话系统会直接打开网页,这是正常行为。
内容的提问来源于stack exchange,提问作者Yogendra Patel




