您可以采取一些措施来改进其他答案。从 iOS 9 开始,可以在UIWebView 或SFSafariViewController 中打开链接。您可能希望以不同的方式处理它们。
SFSafariViewController 在应用程序之间共享 cookie,并与内置的 Safari 共享。因此,在您的应用程序中,您可以通过 SFSafariViewController 发出请求,该请求将设置一个显示“我的应用程序已安装”的 cookie。例如,您打开您的网站,要求您的服务器设置此类 cookie。然后,每当您收到来自 SFSafariViewController 的请求时,您都可以检查该 cookie 并重定向到 MYAPP://(如果找到),或者重定向到应用商店(如果没有)。无需打开网页并执行 javascript 重定向,您可以从您的服务器执行 301。 Messages 或 Safari 等应用共享这些 cookie。
UIWebView 非常棘手,因为它完全被沙盒化并且不与其他任何东西共享任何 cookie。所以你必须回退到其他答案中描述的内容:
window.onload = function() {
var iframe = document.createElement("iframe");
var uri = 'MYAPP://';
var interval = setInterval(function() {
// Link to the App Store should go here -- only fires if deep link fails
window.location = "https://itunes.apple.com/us/app/my.app/id123456789?ls=1&mt=8";
}, 500);
iframe.onload = function() {
clearInterval(interval);
iframe.parentNode.removeChild(iframe);
window.location.href = uri;
};
iframe.src = uri;
iframe.setAttribute("style", "display:none;");
document.body.appendChild(iframe);
};
我发现这很烦人,即使您的应用尚未安装,这也会提示用户是否要离开当前应用(转至您的应用)。 (从经验上看,这似乎只在 UIWebView 中是正确的,如果你在普通的 Safari 中这样做,例如不会发生),但这就是我们所得到的!
您可以将UIWebView 与SFSafariViewController 与您的服务器区分开来,因为它们具有不同的用户代理标头:SFSafariViewController 包含 Safari 而UIWebView 不包含。例如:
Mozilla/5.0 (iPhone; CPU iPhone OS 10_3 like Mac OS X) AppleWebKit/603.1.30 (KHTML, like Gecko) Mobile/14E269
-> UIWebView
Mozilla/5.0 (iPhone; CPU iPhone OS 10_3 like Mac OS X) AppleWebKit/603.1.30 (KHTML, like Gecko) Version/10.0 Mobile/14E269 Safari/602.1
-> SFSafariViewController
其他注意事项:
- 在第一种方法中,您可能希望处理卸载:如果用户卸载您的应用程序,您仍然有一个 cookie 表明该应用程序存在但它不存在,因此您最终可能会收到
"Can not open URL" 消息。我已经通过在几次尝试都没有打开应用程序后删除 cookie 来处理它(我知道,因为在每次打开应用程序时我都会重置这个失败的尝试 cookie)
- 在第二种情况下,不清楚使用
setInterval 还是setTimeout 更好。超时的问题是,如果它在提示打开时触发,它将被忽略。例如,如果您从 Messenger 打开链接,当 iframe 尝试加载您的应用程序时,操作系统会询问您“离开 Messenger?您即将打开另一个应用程序”。如果您在超时的 500 毫秒内均未响应,则超时中的重定向将被忽略。
- 最后,即使
UIWebView 被沙盒化,您也可以给它一个cookie 来识别它,将它传递到您的深层链接中,并在您的应用程序打开时将此ID 保存为与您的应用程序在您的服务器中的设备相对应。下次,如果您在来自UIWebView 的请求中看到这样的 cookie,您可以检查它是否与应用程序的已知设备匹配,并像以前一样直接使用 301 重定向。