iPhone浏览器:检查是否从浏览器安装了iPhone应用程序

时间:2011-09-27 17:55:13

标签: iphone browser

我有一个网页,我有按钮,可以打开应用程序(如果已安装),或者如果未安装应用程序,则指向App Store。 如果安装了App,它都可以工作(我打电话给“MYAPP://”)。但是,如果未安装应用程序,Safari会显示错误消息“无法打开URL”,就是这样。有没有办法从JScript中禁用该消息,或者是否有其他方法可以从JScript中找到安装了应用程序(而不是点击应用程序URL)?

致主持人:我看到有人问similar question,主持人错误地将其标记为重复。请理解该问题具体是关于从浏览器中执行此操作。

找到了一些合适的解决方案here

BTW如果有人对如何为Android做同样的事情感兴趣,这里是代码。我们正在使用Dojo库:

  dojo.io.iframe.send({
    url: "yourApp://foo/bar",
    load: function(resp) {
      // nothing to do since it will automagically open App
    },
    error: function () {
      window.location = "go to Android market";
    }
  });

5 个答案:

答案 0 :(得分:13)

Branch我们使用下面代码的形式 - 请注意,iframe适用于更多浏览器。只需替换您应用的URI和App Store链接即可。顺便说一句,如果他们没有安装应用程序,使用iframe会使错误无效。太棒了!

<!DOCTYPE html>
<html>
    <body>
        <script type="text/javascript">
            window.onload = function() {
                // Deep link to your app goes here
                document.getElementById("l").src = "my_app://";

                setTimeout(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);
            };
        </script>
        <iframe id="l" width="1" height="1" style="visibility:hidden"></iframe>
    </body>
</html>

如果其他人有更好的解决方案来检测URI方案调用是否真的失败了,请发帖!我还没见过一个,我花了很多时间看。所有现有的解决方案都依赖于仍在页面上的用户和setTimeout触发。

答案 1 :(得分:4)

这是一个适用于iOs的代码,即使“无法打开URL”仍然显示。

    window.location = "yourApp://foo/bar";      
    clickedAt = +new Date;
    setTimeout(function() {
        if (+new Date - clickedAt < 2000) {
            window.location = "go to Android market";
        }
    }, 500);

感谢Android解决方案。

答案 2 :(得分:0)

我认为你仍然可以使用app url作为测试。尝试将其包装在try...catch块中,

try {
  //run code that normally breaks the script or throws error
}
catch(e) {
  //do nothing
}

答案 3 :(得分:0)

在使用chazbot的try / catch方法之前,我结合了一些内容并使用以下代码检查它是否是iOS设备。不幸的是,该设备仍向用户抛出一个弹出框,说明该地址无效......任何人都知道这是否是试图在“try”块中打开无效URL的预期行为?

    var i = 0,
    iOS = false,
    iDevice = ['iPad', 'iPhone', 'iPod'];

    for ( ; i < iDevice.length ; i++ ) {
        if( navigator.platform === iDevice[i] ){ iOS = true; break; }
    }

    try {
        //run code that normally breaks the script or throws error
        if (iOS) { window.location = "myApp://open";}
    }
    catch(e) {
        //do nothing
    }

答案 4 :(得分:0)

您可以采取一些措施来改进其他答案。自iOS 9起,可以在UIWebViewSFSafariViewController中打开链接。您可能希望以不同方式处理它们。

SFSafariViewController在应用程序和内置Safari中共享Cookie。因此,在您的应用中,您可以通过SFSafariViewController发出请求,该请求会设置一个Cookie,其中包含&#34;我的应用已安装&#34;。例如,您打开您的网站,要求您的服务器设置此类cookie。然后,只要您收到来自SFSafariViewController的请求,就可以检查该Cookie并在找到时重定向到MYAPP://,如果您没有,则转到应用商店。无需打开网页并进行javascript重定向,您可以从服务器执行301。 MessagesSafari等应用共享这些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那样做,例如那不会发生)但是我们得到了所有这些!

您可以将UIWebViewSFSafariViewController区分开来,因为它们具有不同的用户代理标头:SFSafariViewController包含 Safari ,而{{1没有。例如:

UIWebView

其他考虑因素:

  • 在第一种方法中,您可能希望处理卸载:如果用户卸载了您的应用,您仍然会有一个Cookie,表明该应用已存在,但它不存在,因此您最终可能会使用{ {1}}消息。我已经通过几次尝试删除了cookie来处理它,但最终没有打开应用程序(我知道因为在每个应用程序打开时我都会重置这个失败的尝试cookie)
  • 在第二种情况下,我们不清楚您是否最好使用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 "Can not open URL"。超时问题是,如果在启用提示时触发,则会被忽略。例如,如果你打开Messenger的链接,操作系统会问你&#34;离开Messenger?您即将开设另一个应用程序&#34;当iframe尝试加载您的应用时。如果你没有在超时的500毫秒内做出任何反应,那么超时中的重定向将被忽略。
  • 最后即使setInterval是沙盒,您也可以给它一个cookie来识别它,在深层链接中传递它,并在您的应用打开时将此ID与您服务器中的应用相对应。下次,如果您在来自setTimeout的请求中看到此类Cookie,则可以检查它是否与应用程序中的已知设备匹配,并像以前一样直接使用301重定向。