ios 如何检查是否从 iPhone 上的网页安装了应用程序?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/13044805/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to check if an app is installed from a web-page on an iPhone?
提问by Joakim Engstrom
I want to create a web-page, a page that will redirect an iPhone to the app-store if the iPhone does not have the application installed, but if the iPhone has the app installed I want it to open the application.
我想创建一个网页,如果 iPhone 没有安装应用程序,这个页面会将 iPhone 重定向到应用程序商店,但如果 iPhone 安装了应用程序,我希望它打开应用程序。
I have already implemented a custom url in the iPhone application so I have an url for the application that is something like:
我已经在 iPhone 应用程序中实现了一个自定义 url,所以我有一个应用程序的 url,类似于:
myapp://
And if this url is invalid, I want the page to redirect to the app store. Is this possible at all?
如果此 url 无效,我希望页面重定向到应用商店。这可能吗?
If I don't have the application installed on the phone and write the myapp:// url in safari, all I get is an error message.
如果我没有在手机上安装应用程序并在 safari 中写入 myapp:// url,我得到的只是一条错误消息。
Even if there exists an ugly hack with javascript I would really like to know?
即使我真的很想知道javascript存在一个丑陋的黑客攻击?
回答by missemisa
As far as I know you can not, from a browser, check if an app is installed or not.
据我所知,您无法从浏览器检查是否安装了应用程序。
But you can try redirecting the phone to the app, and if nothing happens redirect the phone to a specified page, like this:
但是您可以尝试将手机重定向到应用程序,如果没有任何反应,则将手机重定向到指定页面,如下所示:
setTimeout(function () { window.location = "https://itunes.apple.com/appdir"; }, 25);
window.location = "appname://";
If the second line of code gives a result then the first row is never executed.
如果第二行代码给出结果,则永远不会执行第一行。
Hope this helps!
希望这可以帮助!
Similar question:
类似问题:
回答by Alastair
To further the accepted answer, you sometimes need to add extra code to handle people returning the browser after launching the app- that setTimeout function will run whenever they do. So, I do something like this:
为了进一步接受答案,您有时需要添加额外的代码来处理启动应用程序后返回浏览器的人 - 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://";
That way, if there has been a freeze in code execution (i.e., app switching), it won't run.
这样,如果代码执行(即应用程序切换)出现冻结,它就不会运行。
回答by brainjam
iOS Safari has a feature that allows you to add a "smart" banner to your webpage that will link either to your app, if it is installed, or to the App Store.
iOS Safari 具有一项功能,可让您向网页添加“智能”横幅,该横幅将链接到您的应用程序(如果已安装)或 App Store。
You do this by adding a meta
tag to the page. You can even specify a detailed app URL if you want the app to do something special when it loads.
您可以通过向meta
页面添加标签来完成此操作。如果您希望应用程序在加载时执行某些特殊操作,您甚至可以指定详细的应用程序 URL。
Details are at Apple's Promoting Apps with Smart App Bannerspage.
详细信息位于 Apple 的使用智能应用横幅页面推广应用程序。
The mechanism has the advantages of being easy and presenting a standardized banner. The downside is that you don't have much control over the look or location. Also, all bets are off if the page is viewed in a browser other than Safari.
该机制的优点是简单,呈现标准化的横幅。缺点是您无法控制外观或位置。此外,如果在 Safari 以外的浏览器中查看页面,则所有赌注都将关闭。
回答by Sebastien Lorber
As of 2017, it seems there's no reliable way to detect an app is installed, and the redirection trick won't work everywhere.
截至 2017 年,似乎没有可靠的方法来检测已安装的应用程序,并且重定向技巧在任何地方都不起作用。
For those like me who needs to deep link directly from emails (quite common), it is worth noting the following:
对于像我这样需要直接从电子邮件进行深度链接的人(很常见),值得注意以下几点:
Sending emails with appScheme:// won't work fine because the links will be filtered in Gmail
Redirecting automatically to appScheme:// is blocked by Chrome: I suspect Chrome requires the redirection to be synchronous to an user interaction (like a click)
You can now deep link without appScheme:// and it's better but it requires a modern platform and additional setup. AndroidiOS
使用 appScheme:// 发送电子邮件将无法正常工作,因为链接将在 Gmail 中被过滤
自动重定向到 appScheme:// 被 Chrome 阻止:我怀疑 Chrome 需要重定向与用户交互同步(如点击)
您现在可以在没有 appScheme:// 的情况下进行深度链接,这更好,但它需要一个现代平台和额外的设置。Android的iOS版
It is worth noting that other people already thought about this in depth. If you look at how Slack implements his "magic link" feature, you can notice that:
值得注意的是,其他人已经对此进行了深入思考。如果您查看 Slack 如何实现他的“魔术链接”功能,您会注意到:
- It sends an email with a regular http link (ok with Gmail)
- The web page have a big button that links to appScheme:// (ok with Chrome)
- 它发送一封带有常规 http 链接的电子邮件(使用 Gmail 可以)
- 该网页有一个链接到 appScheme:// 的大按钮(适用于 Chrome)
回答by hampusohlsson
You can check out this plugin that tries to solve the problem. It is based on the same approach as described by missemisa and Alastair etc, but uses a hidden iframe instead.
您可以查看这个试图解决问题的插件。它基于与 Missemisa 和 Alastair 等描述的方法相同的方法,但使用隐藏的 iframe 代替。
回答by brainjam
@Alistair pointed out in this answerthat sometimes users will return to the browser after opening the app. A commenter to that answer indicated that the times values used had to be changed depending on iOS version. When our team had to deal with this, we found that the time values for the initial timeout and telling whether we had returned to the browser had to be tuned, and often didn't work for all users and devices.
@Alistair 在此回答中指出,有时用户会在打开应用程序后返回浏览器。该答案的评论者表示,必须根据 iOS 版本更改使用的时间值。当我们的团队不得不处理这个问题时,我们发现初始超时和判断是否返回浏览器的时间值必须进行调整,并且通常不适用于所有用户和设备。
Rather than using an arbitrary time difference threshold to determine whether we had returned to the browser, it made sense to detect the "pagehide" and "pageshow" events.
与其使用任意时间差阈值来确定我们是否已返回浏览器,不如检测“pagehide”和“pageshow”事件。
I developed the following web page to help diagnose what was going on. It adds HTML diagnostics as the events unfold, mainly because using techniques like console logging, alerts, or Web Inspector, jsfiddle.net etc all had their drawbacks in this work flow. Rather than using a time threshold, the Javascript counts the number of "pagehide" and "pageshow" events to see whether they have occurred. And I found that the most robust strategy was to use an initial timeout of 1000 (rather than the 25, 50, or 100 reported/suggested by others).
我开发了以下网页来帮助诊断发生了什么。它在事件展开时添加 HTML 诊断,主要是因为使用控制台日志记录、警报或 Web Inspector、jsfiddle.net 等技术在此工作流程中都有其缺点。Javascript 不使用时间阈值,而是计算“pagehide”和“pageshow”事件的数量,以查看它们是否发生。我发现最可靠的策略是使用 1000 的初始超时(而不是其他人报告/建议的 25、50 或 100)。
This can be served on a local server, e.g. python -m SimpleHTTPServer
and viewed on iOS Safari.
这可以在本地服务器上提供,例如python -m SimpleHTTPServer
在 iOS Safari 上查看。
To play with it, press either the "Open an installed app" or "App not installed" links. These links should cause respectively the Maps app or the App Store to open. You can then return to Safari to see the sequence and timing of the events.
要使用它,请按“打开已安装的应用程序”或“未安装应用程序”链接。这些链接应分别导致地图应用程序或 App Store 打开。然后您可以返回到 Safari 以查看事件的顺序和时间。
(Note: this will work for Safari only. For other browsers (like Chrome) you'd have to install handlers for the pagehide/show-equivalent events).
(注意:这仅适用于 Safari。对于其他浏览器(如 Chrome),您必须为 pagehide/show-equivalent 事件安装处理程序)。
Update:As @Mikko has pointed out in the comments, the pageshow/pagehide events we are using are apparently no longer supported in iOS8.
更新:正如@Mikko 在评论中指出的那样,iOS8 显然不再支持我们正在使用的 pageshow/pagehide 事件。
<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>
回答by nate_weldon
I need to do something like this I ended up going with the following solution.
我需要做这样的事情我最终采用了以下解决方案。
I have a specific website URL that will open a page with two buttons
我有一个特定的网站 URL,它将打开一个带有两个按钮的页面
1) Button One go to website
1)按钮一去网站
2) Button Two go to application (iphone / android phone / tablet) you can fall back to a default location from here if the app is not installed (like another url or an app store)
2)按钮二转到应用程序(iphone / android手机/平板电脑),如果未安装该应用程序(如另一个网址或应用程序商店),您可以从这里退回到默认位置
3) cookie to remember users choice
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"> </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>
回答by ptrk
After compiling a few answers, I've come up with the following code. What surprised me was that the timer does notget frozen on a PC (Chrome, FF) or Android Chrome - the trigger worked in the background, and the visibility check was the only reliable info.
编译了几个答案后,我想出了以下代码。让我吃惊的是,计时器也没有得到一个PC(浏览器,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://');
回答by Magico
The date solution is much better than others, I had to increment the time on 50 like that this is a Tweeter example:
日期解决方案比其他解决方案要好得多,我不得不将时间增加到 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;
the only problem on Mobile IOS Safari is when you don't have the app installed on device, and so Safari show an alert that autodismiss when the new url is opened, anyway is a good solution for now!
Mobile IOS Safari 的唯一问题是当您没有在设备上安装该应用程序时,因此 Safari 会在打开新 url 时显示自动关闭的警报,无论如何现在是一个很好的解决方案!
回答by 1.21 gigawatts
Didn't read all of these but may be use an iframe and adding the source to, "my app://whatever".
没有阅读所有这些,但可能会使用 iframe 并将源添加到“我的应用程序://随便”。
Then check regularly on set interval of the page is 404or not.
然后定期检查页面的设置间隔是否为404。
You could also use Ajax call. If 404 response then app is not installed.
您也可以使用 Ajax 调用。如果 404 响应,则未安装应用程序。