Браузер iPhone: проверка наличия приложения iPhone из браузера
У меня есть веб-страница, на которой у меня есть Button, которая либо открывает приложение (если оно установлено), либо направляет в App Store, если приложение не установлено.
Все работает, если приложение установлено (я звоню в "MYAPP://" ). Однако, если приложение не установлено, Safari показывает сообщение об ошибке "Не удается открыть URL" и что он. Есть ли способ отключить это сообщение от JScript или есть другой способ узнать из JScript, если приложение установлено (вместо того, чтобы удалять URL-адрес приложения)?
К MODERATOR: Я видел, что кто-то спросил аналогичный вопрос, а Модератор ошибочно отметил его как дубликат. Пожалуйста, поймите, что речь идет конкретно о том, чтобы делать это из браузера.
Нашел несколько подходящее решение здесь
Кстати, если кто-то заинтересован в том, как сделать то же самое для 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";
}
});
Ответы
Ответ 1
В 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.
Ответ 2
Вот код, который работает на 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.
Ответ 3
Я думаю, что вы все равно можете использовать URL-адрес приложения в качестве теста. Попробуйте обернуть его в блок try...catch
,
try {
//run code that normally breaks the script or throws error
}
catch(e) {
//do nothing
}
Ответ 4
Я объединил несколько вещей и использовал следующий код, чтобы проверить, не является ли это iOS-устройством перед использованием метода try/catch из chazbot. К сожалению, устройство по-прежнему выбрасывает всплывающее окно для пользователя, указав, что адрес недопустим... кто-нибудь знает, если это ожидаемое поведение для попытки открыть недопустимый URL-адрес в блоке "try"?
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
}
Ответ 5
Есть несколько вещей, которые вы можете сделать, чтобы улучшить другие ответы. Начиная с iOS 9, ссылку можно открыть в UIWebView
или в SFSafariViewController
. Возможно, вы захотите обработать их по-другому.
SFSafariViewController
использует файлы cookie в приложениях и со встроенным Safari. Таким образом, в вашем приложении вы можете сделать запрос через SFSafariViewController
, который установит файл cookie, в котором говорится, что "мое приложение установлено". Например, вы открываете свой веб-сайт, предлагая своему серверу установить такой файл cookie. Затем в любое время, когда вы получаете запрос от SFSafariViewController
, вы можете проверить этот файл cookie и перенаправить на MYAPP://
, если вы его найдете, или в магазин приложений, если вы этого не сделаете. Не нужно открывать веб-страницу и выполнять перенаправление javascript, вы можете сделать 301 с вашего сервера. Приложения, такие как Messages
или Safari
, совместно используют эти файлы 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, например, это не произойдет), но все, что у нас получилось!
Вы можете отличить UIWebView
от SFSafariViewController
от вашего сервера, поскольку у них есть другой заголовок агента пользователя: SFSafariViewController
содержит Safari, а UIWebView
- нет. Например:
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
Другие соображения:
- в первом подходе вам может понадобиться обработать uninstalls: если пользователь удаляет ваше приложение, у вас все еще есть куки файл, в котором говорится, что приложение есть, но оно отсутствует, поэтому вы можете вступить в сообщение
"Can not open URL"
. Я обработал его, удалив куки файл после нескольких попыток, которые не закончили открывать приложение (что я знаю, потому что при каждом открытии приложения я сбрасываю этот файл с ошибками.)
- Во втором случае неясно, лучше ли вам использовать
setInterval
или setTimeout
. Проблема с таймаутом заключается в том, что если он запускается во время включения приглашения, он будет проигнорирован. Например, если вы откроете ссылку из Messenger, os спросит вас: "Оставьте Messenger? Вы собираетесь открыть другое приложение", когда iframe пытается загрузить ваше приложение. Если вы не ответите ни разу в течение 500 мс таймаута, перенаправление в таймаут будет проигнорировано.
- Наконец, несмотря на то, что
UIWebView
изолирован песочницей, вы можете дать ему куки файл, чтобы идентифицировать его, передать его в свой deeplink и сохранить этот идентификатор как соответствующий устройству с вашим приложением на вашем сервере при открытии вашего приложения. В следующий раз, если вы увидите такой файл cookie в запросе, исходящем от UIWebView
, вы можете проверить, совпадает ли он с известным устройством с приложением и перенаправить напрямую с 301.