首页 文章

如何检查iPhone上的网页是否安装了应用程序?

提问于
浏览
120

我想创建一个网页,如果iPhone没有安装应用程序,将iPhone重定向到应用程序商店的页面,但如果iPhone安装了应用程序,我希望它打开应用程序 .

我已经在iPhone应用程序中实现了一个自定义URL,所以我有一个应用程序的URL,如下所示:

myapp://

如果此网址无效,我希望该网页重定向到应用商店 . 这有可能吗?

如果我没有在手机上安装应用程序并在safari中编写myapp:// url,我得到的只是一条错误消息 .

即使存在javascript的丑陋黑客,我真的想知道吗?

10 回答

  • 166

    据我所知,您无法通过浏览器检查是否安装了应用程序 .

    但您可以尝试将手机重定向到应用程序,如果没有任何反应,请将手机重定向到指定的页面,如下所示:

    setTimeout(function () { window.location = "https://itunes.apple.com/appdir"; }, 25);
    window.location = "appname://";
    

    如果第二行代码给出结果,则永远不会执行第一行 .

    希望这可以帮助!

    类似的问题:

  • 9

    为了进一步接受已接受的答案,您有时需要添加额外的代码来处理启动应用程序后返回浏览器的人员 - 只要他们这样做,setTimeout函数就会运行 . 所以,我做这样的事情:

    var now = new Date().valueOf();
    setTimeout(function () {
        if (new Date().valueOf() - now > 100) return;
        window.location = "https://itunes.apple.com/appdir";
    }, 25);
    window.location = "appname://";
    

    这样,如果代码执行冻结(即应用程序切换),它将无法运行 .

  • 1

    iOS Safari具有一项功能,允许您在网页中添加“智能” Banner ,该 Banner 将链接到您的应用程序(如果已安装)或App Store .

    您可以通过向页面添加 meta 标记来完成此操作 . 如果您希望应用在加载时执行特殊操作,您甚至可以指定详细的应用URL .

    详情请见Apple的Promoting Apps with Smart App Banners页面 .

    该机制具有易于呈现标准化 Banner 的优点 . 缺点是您无法控制外观或位置 . 此外,如果在Safari以外的浏览器中查看页面,则所有投注均已关闭 .

  • 2

    您可以查看试图解决问题的插件 . 它基于missemisa和Alastair等描述的相同方法,但使用隐藏的iframe代替 .

    https://github.com/hampusohlsson/browser-deeplink

  • -2

    @Alistair在this answer指出,有时用户在打开应用程序后会返回浏览器 . 该答案的评论者表示,使用的时间值必须根据iOS版本进行更改 . 当我们的团队不得不处理这个问题时,我们发现初始超时的时间值以及我们是否已经返回浏览器必须进行调整,并且通常不适用于所有用户和设备 .

    不是使用任意时间差阈值来确定我们是否已返回浏览器,而是检测“pagehide”和“pageshow”事件是有意义的 .

    我开发了以下网页来帮助诊断发生了什么 . 它随着事件的展开而增加了HTML诊断功能,主要是因为使用控制台日志记录,警报或Web Inspector,jsfiddle.net等技术都在这个工作流程中存在缺陷 . Javascript不是使用时间阈值,而是计算“pagehide”和“pageshow”事件的数量,以查看它们是否已经发生 . 我发现最强大的策略是使用1000的初始超时(而不是其他人报告/建议的25,50或100) .

    这可以在本地服务器上提供,例如, python -m SimpleHTTPServer 并在iOS Safari上查看 .

    要使用它,请按“打开已安装的应用程序”或“未安装应用程序”链接 . 这些链接应分别导致 Map 应用程序或App Store打开 . 然后,您可以返回Safari以查看事件的顺序和时间 .

    (注意:这仅适用于Safari . 对于其他浏览器(如Chrome),您必须为pagehide / show-equivalent事件安装处理程序) .

    Update: 正如@Mikko在评论中指出的那样,iOS8中显然不再支持我们正在使用的pageshow / pagehide事件 .

    <html>
    <head>
    </head>
    <body>
    <a href="maps://" onclick="clickHandler()">Open an installed app</a>
    

    <a href="xmapsx://" onclick="clickHandler()">App not installed</a>
    <script> var hideShowCount = 0 ; window.addEventListener("pagehide", function() { hideShowCount++ ; showEventTime('pagehide') ; }); window.addEventListener("pageshow", function() { hideShowCount++ ; showEventTime('pageshow') ; }); function clickHandler(){ var hideShowCountAtClick = hideShowCount ; showEventTime('click') ; setTimeout(function () { showEventTime('timeout function '+(hideShowCount-hideShowCountAtClick)+' hide/show events') ; if (hideShowCount == hideShowCountAtClick){ // app is not installed, go to App Store window.location = 'http://itunes.apple.com/app' ; } }, 1000); } function currentTime() { return Date.now()/1000 ; } function showEventTime(event){ var time = currentTime() ; document.body.appendChild(document.createElement('br')); document.body.appendChild(document.createTextNode(time+' '+event)); } </script> </body> </html>
  • 27

    截至2017年,似乎没有可靠的方法来检测安装的应用程序,并且重定向技巧无处不在 .

    对于像我这样需要直接从电子邮件深层链接的人(很常见),值得注意以下几点:

    • 使用appScheme://发送电子邮件将无效,因为链接将在Gmail中过滤

    • 自动重定向到appScheme://被Chrome阻止:我怀疑Chrome需要重定向与用户交互同步(如点击)

    • 您现在可以在没有appScheme的情况下进行深层链接://并且它更好,但它需要一个现代平台和其他设置 . Android iOS


    值得注意的是,其他人已经深入思考了这一点 . 如果你看看Slack如何实现他的“魔术链接”功能,你会注意到:

    • 它会发送一封包含常规http链接的电子邮件(可以使用Gmail)

    • 该网页有一个大按钮,链接到appScheme://(确定Chrome)

  • -3

    我需要做这样的事情,我最终得到了以下解决方案 .

    我有一个特定的网站URL,将打开一个带有两个按钮的页面

    1)按钮一转到网站

    2)按钮2转到应用程序(iphone / android手机/平板电脑)如果未安装应用程序(如其他网址或应用程序商店),您可以从此处回退到默认位置

    3)cookie记住用户选择

    <head>
    <title>Mobile Router Example </title>
    
    
    <script type="text/javascript">
        function set_cookie(name,value)
        {
           // js code to write cookie
        }
        function read_cookie(name) {
           // jsCode to read cookie
        }
    
        function goToApp(appLocation) {
            setTimeout(function() {
                window.location = appLocation;
                  //this is a fallback if the app is not installed. Could direct to an app store or a website telling user how to get app
    
    
            }, 25);
            window.location = "custom-uri://AppShouldListenForThis";
        }
    
        function goToWeb(webLocation) {
            window.location = webLocation;
        }
    
        if (readCookie('appLinkIgnoreWeb') == 'true' ) {
            goToWeb('http://somewebsite');
    
        }
        else if (readCookie('appLinkIgnoreApp') == 'true') {
            goToApp('http://fallbackLocation');
        }
    
    
    
    </script>
    </head>
    <body>
    
    
    <div class="iphone_table_padding">
    <table border="0" cellspacing="0" cellpadding="0" style="width:100%;">
        <tr>
            <td class="iphone_table_leftRight">&nbsp;</td>
            <td>
                <!-- INTRO -->
                <span class="iphone_copy_intro">Check out our new app or go to website</span>
            </td>
            <td class="iphone_table_leftRight">&nbsp;</td>
        </tr>
        <tr>
            <td class="iphone_table_leftRight">&nbsp;</td>
            <td>
                <div class="iphone_btn_padding">
    
                    <!-- GET IPHONE APP BTN -->
                    <table border="0" cellspacing="0" cellpadding="0" class="iphone_btn" onclick="set_cookie('appLinkIgnoreApp',document.getElementById('chkDontShow').checked);goToApp('http://getappfallback')">
                        <tr>
                            <td class="iphone_btn_on_left">&nbsp;</td>
                            <td class="iphone_btn_on_mid">
                                <span class="iphone_copy_btn">
                                    Get The Mobile Applications
                                </span>
                            </td>
                            <td class="iphone_btn_on_right">&nbsp;</td>
                        </tr>
                    </table>
    
                </div>
            </td>
            <td class="iphone_table_leftRight">&nbsp;</td>
        </tr>
        <tr>
            <td class="iphone_table_leftRight">&nbsp;</td>
            <td>
                <div class="iphone_btn_padding">
    
                    <table border="0" cellspacing="0" cellpadding="0" class="iphone_btn"  onclick="set_cookie('appLinkIgnoreWeb',document.getElementById('chkDontShow').checked);goToWeb('http://www.website.com')">
                        <tr>
                            <td class="iphone_btn_left">&nbsp;</td>
                            <td class="iphone_btn_mid">
                                <span class="iphone_copy_btn">
                                    Visit Website.com
                                </span>
                            </td>
                            <td class="iphone_btn_right">&nbsp;</td>
                        </tr>
                    </table>
    
                </div>
            </td>
            <td class="iphone_table_leftRight">&nbsp;</td>
        </tr>
        <tr>
            <td class="iphone_table_leftRight">&nbsp;</td>
            <td>
                <div class="iphone_chk_padding">
    
                    <!-- CHECK BOX -->
                    <table border="0" cellspacing="0" cellpadding="0">
                        <tr>
                            <td><input type="checkbox" id="chkDontShow" /></td>
                            <td>
                                <span class="iphone_copy_chk">
                                    <label for="chkDontShow">&nbsp;Don&rsquo;t show this screen again.</label>
                                </span>
                            </td>
                        </tr>
                    </table>
    
                </div>
            </td>
            <td class="iphone_table_leftRight">&nbsp;</td>
        </tr>
    </table>
    
    </div>
    
    </body>
    </html>
    
  • 141

    编译几个答案后,我想出了以下代码 . 让我感到惊讶的是,计时器不会在PC(Chrome,FF)或Android Chrome上被冻结 - 触发器在后台运行,并且可见性检查是唯一可靠的信息 .

    var timestamp             = new Date().getTime();
    var timerDelay              = 5000;
    var processingBuffer  = 2000;
    
    var redirect = function(url) {
      //window.location = url;
      log('ts: ' + timestamp + '; redirecting to: ' + url);
    }
    var isPageHidden = function() {
        var browserSpecificProps = {hidden:1, mozHidden:1, msHidden:1, webkitHidden:1};
        for (var p in browserSpecificProps) {
            if(typeof document[p] !== "undefined"){
            return document[p];
          }
        }
        return false; // actually inconclusive, assuming not
    }
    var elapsedMoreTimeThanTimerSet = function(){
        var elapsed = new Date().getTime() - timestamp;
      log('elapsed: ' + elapsed);
      return timerDelay + processingBuffer < elapsed;
    }
    var redirectToFallbackIfBrowserStillActive = function() {
      var elapsedMore = elapsedMoreTimeThanTimerSet();
      log('hidden:' + isPageHidden() +'; time: '+ elapsedMore);
      if (isPageHidden() || elapsedMore) {
        log('not redirecting');
      }else{
        redirect('appStoreUrl');
      }
    }
    var log = function(msg){
        document.getElementById('log').innerHTML += msg + "<br>";
    }
    
    setTimeout(redirectToFallbackIfBrowserStillActive, timerDelay);
    redirect('nativeApp://');
    

    JS Fiddle

  • 6

    日期解决方案比其他解决方案好得多,我不得不增加50的时间,就像这是一个Tweeter示例:

    //on click or your event handler..
    var twMessage = "Your Message to share";
    var now = new Date().valueOf();
    setTimeout(function () {
       if (new Date().valueOf() - now > 100) return;
       var twitterUrl = "https://twitter.com/share?text="+twMessage;
       window.open(twitterUrl, '_blank');
    }, 50);
    window.location = "twitter://post?message="+twMessage;
    

    移动IOS Safari上唯一的问题是当你没有在设备上安装应用程序时,因此Safari会在新网址打开时显示自动发出警报,无论如何现在都是一个很好的解决方案!

  • 9

    没有阅读所有这些,但可能使用iframe并将源添加到“我的app://无论什么” .

    然后定期检查页面的设置间隔是404或不 .

    您也可以使用Ajax调用 . 如果404响应则不安装app .

相关问题