如何检查一个应用程序是从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来代替。
@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"> </td> <td> <!-- INTRO --> <span class="iphone_copy_intro">Check out our new app or go to website</span> </td> <td class="iphone_table_leftRight"> </td> </tr> <tr> <td class="iphone_table_leftRight"> </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"> </td> <td class="iphone_btn_on_mid"> <span class="iphone_copy_btn"> Get The Mobile Applications </span> </td> <td class="iphone_btn_on_right"> </td> </tr> </table> </div> </td> <td class="iphone_table_leftRight"> </td> </tr> <tr> <td class="iphone_table_leftRight"> </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"> </td> <td class="iphone_btn_mid"> <span class="iphone_copy_btn"> Visit Website.com </span> </td> <td class="iphone_btn_right"> </td> </tr> </table> </div> </td> <td class="iphone_table_leftRight"> </td> </tr> <tr> <td class="iphone_table_leftRight"> </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"> Don’t show this screen again.</label> </span> </td> </tr> </table> </div> </td> <td class="iphone_table_leftRight"> </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!