如何检查一个应用程序是从iPhone上的网页安装?

我想要创build一个web页面,如果iPhone没有安装应用程序,将把iPhoneredirect到应用程序商店,但是如果iPhone安装了应用程序,我希望它打开应用程序。

我已经在iPhone应用程序中实现了一个自定义url,所以我有一个类似于以下内容的应用程序的url:

myapp:// 

如果此url无效,我希望网页redirect到app store。 这可能吗?

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

即使有JavaScript的丑陋黑客我真的想知道?

据我所知,你不能从浏览器,检查是否安装了应用程序。

但是,您可以尝试将手机redirect到应用程序,如果没有任何操作将手机redirect到指定页面,如下所示:

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

如果第二行代码给出结果,那么第一行永远不会执行。

希望这可以帮助!

类似的问题:

  • iPhone浏览器:检查iPhone应用程序是否从浏览器安装
  • 是否有可能注册一个基于http +域名的iPhone应用程序的URL计划,如YouTube和地图?

为了进一步接受答案,有时需要添加额外的代码来处理启动应用程序后返回浏览器的人 – 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://"; 

这样,如果在代码执行(即应用程序切换)中已经冻结,它将不会运行。

iOS Safari具有一项function,可让您在网页上添加一个“智能”横幅,将其链接到您的应用程序(如果已安装)或App Store。

您可以通过向页面添加meta标记来完成此操作。 你甚至可以指定一个详细的应用程序的URL,如果你想让应用程序加载时做一些特殊的事情。

详细信息请访问Apple的“ 促销应用程序和智能应用程序横幅”页面。

该机制具有容易和提出标准化的横幅的优点。 缺点是你没有太多的控制外观或位置。 此外,如果在Safari浏览器以外的浏览器中查看页面,则所有投注都将closures。

你可以看看这个试图解决问题的插件。 它基于与missemisa和Alastair等描述的相同的方法,但是使用隐藏的iframe来代替。

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

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

而不是使用任意的时间差阈值来确定我们是否已经返回到浏览器,检测“页面隐藏”和“页面显示”事件是有意义的。

我开发了以下网页来帮助诊断正在发生的事情。 它随着事件展开而添加了HTML诊断,主要是因为使用诸如控制台日志,警报或Web Inspector,jsfiddle.net等技术在这个工作stream程中都有其缺陷。 Javascript不是使用时间阈值,而是计算“页面隐藏”和“页面显示”事件的数量,以查看它们是否已经发生。 而且我发现最稳健的策略是使用1000的初始超时(而不是其他人报告/build议的25,50或100)。

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

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

(注意:这只适用于Safari浏览器,对于其他浏览器(如Chrome浏览器),您必须为页面隐藏/显示等效事件安装处理程序。

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

 <html> <head> </head> <body> <a href="maps://" onclick="clickHandler()">Open an installed app</a> <br/><br/> <a href="xmapsx://" onclick="clickHandler()">App not installed</a> <br/> <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> 

我需要做这样的事情,我最终以下面的解决scheme。

我有一个特定的网站url,将打开一个页面有两个button

1)button一个去网站

2)button两个去应用程序(iPhone / Android手机/平板电脑),如果应用程序没有安装(如另一个url或应用程序商店),您可以从这里回到默认位置。

3)cookie记住用户的select

 <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> 

编译一些答案后,我已经拿出下面的代码。 让我感到惊讶的是,计时器不会在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小提琴

截至2017年,似乎没有可靠的方式来检测应用程序安装,并redirect技巧将无处不在。

对于像我这样需要直接从电子邮件直接链接的人来说(很常见),值得注意的是:

  • 使用appScheme://发送电子邮件将无法正常工作,因为链接将在Gmail中被过滤

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

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


值得注意的是,其他人已经深入的思考过这个问题。 如果你看看Slack如何实现他的“魔术链接”function,你可以注意到:

  • 它发送一个电子邮件与正常的http链接(确定与Gmail)
  • 该网页有一个大的button,链接到appScheme://(与Chrome确定)

没有阅读所有这些,但可能会使用一个iframe,并添加源,“我的应用程序:/ /无论”。

然后定期检查页面的设置间隔是否404。

你也可以使用Ajax调用。 如果404响应,那么应用程序没有安装。

date解决scheme比其他更好,我不得不增加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; 

Mobile IOS Safari的唯一问题是当你没有在设备上安装应用程序,所以Safari显示一个警告,当新的URL被打开时自动发布,无论如何是一个很好的解决scheme!

Interesting Posts