アプリがiPhoneのWebページからインストールされているかどうかを確認する方法


142

iPhoneにアプリケーションがインストールされていない場合にiPhoneをapp-storeにリダイレクトするWebページを作成したいのですが、iPhoneにアプリケーションがインストールされている場合は、アプリケーションでアプリケーションを開きます。

iPhoneアプリケーションに既にカスタムURLを実装しているので、次のようなアプリケーションのURLを取得しています。

myapp://

このURLが無効な場合、ページをアプリストアにリダイレクトします。これはまったく可能ですか?

アプリケーションを電話にインストールしておらず、myapp:// URLをSafariに書き込むと、エラーメッセージだけが表示されます。

javascriptによる醜いハックがあったとしても、本当に知りたいのですか?


1
これはすべてのiOSバージョンで変化し続けます-iOS9は再びすべてを壊しました。これを処理するには、branch.ioのようなサービスを使用することをお勧めします。私はブランチリンクサービスのパーツの構築を手伝い、現在6000を超えるリダイレクトエッジケースを処理しています...
Alex Austin

1
2017年にメールからアプリにリンクする必要がある場合は、私の答えを
ご覧

回答:


199

私が知る限り、ブラウザから、アプリがインストールされているかどうかを確認します。

ただし、電話をアプリにリダイレクトしてみてください。何も起こらない場合は、次のように指定したページに電話をリダイレクトしてください。

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

コードの2行目で結果が得られた場合、最初の行は実行されません。

お役に立てれば!

同様の質問:


20
現在iOS 6.1.2では、これはwebappモードでのみ機能するようです。ブラウザーから直接アプリを使用している場合、期待どおりに外部アプリが開きますが、タイムアウトも発生し、ブラウザーがリダイレクトされます。
Mika Tuupola 2013年

iOSとAndroidのこのようなソリューションが必要でした。この回答がクロスプラットフォームソリューションに統合されていることがわかりました:gist.github.com/FokkeZB/6635236#file-all-in-one-php
Justin

4
アプリがインストールされていない場合、醜い「ページが見つかりません」という警告がスローされます。とにかくそれを抑制することができます
Akshat Agarwal

3
@AkshatAgarwal、「ページが見つかりませんアラート」を抑制するためのコーディング方法について詳しく教えてください
Harpreet

2
これをAndroidとiOSの両方に実装する新しい方法があります。見てみましょうAndroidのアプリのリンクiOSのユニバーサルリンク
maledr53

157

受け入れられた回答をさらに進めるために、時々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://";

このようにして、コードの実行がフリーズした場合(つまり、アプリの切り替え)、それは実行されません。


2
このソリューションは他のソリューションよりもはるかに優れています。50の時間を増やす必要がありました
Magico 2013年

1
iOS 7で失敗するという私のコメントは誤りでした。100ミリ秒を数秒に増やすだけでした(とにかく、それほど短くする必要はありません)。
devios1 2013年

itunes.apple.com/appdirの代わりに、ステップを保存し(httpリダイレクトを待たずに)、アプリストアのURLスキームに直接リンクします。例:itms://itunes.apple.com/us/app/yelp/id284910350
Justin

iOSアプリでは問題なく機能し、Androidアプリでは同じコードが両方のURLに同時にリダイレクトされます。あなたはアプリとプレイストアを開くためにアンドロイドのためにしましたか?
Mehul Dudhat、2014年

5
これにより、50でも、私のアプリとアプリストアの両方が常に開かれます。iOS 12
Josh Wolff

27

iOS Safariには、「スマート」バナーをWebページに追加できる機能があり、インストールされている場合はアプリに、またはApp Storeにリンクされます。

これを行うmetaには、ページにタグを追加します。アプリが読み込まれたときに特別な処理を行う場合は、詳細なアプリのURLを指定することもできます。

詳細はAppleのSmart App Bannersを使ったアプリ宣伝ページにあります。

このメカニズムには、簡単で標準化されたバナーを表示できるという利点があります。欠点は、外観や場所をあまり制御できないことです。また、ページがSafari以外のブラウザで表示されている場合、すべての賭けは無効になります。


2
しかし、ユーザーがインストールしていない場合、アプリのバナーは表示されません
TomSawyer

ユニバーサルリンクもスマートバナーも機能しません。異なるアプリへの複数のネイティブアプリリンクが必要です。Check IFがインストールされているものをそれぞれ起動し、それ以外の場合はストアに移動します。また、ユニバーサルリンクの所有権ファイルをアップロードするドメインを制御できません。したがって、どちらのオプションも私には禁止されています。純粋なJavaScriptソリューションが必要です。
FranticRock

16

2017年現在、アプリがインストールされていることを検出する信頼できる方法はないようで、リダイレクトトリックはどこでも機能しません。

電子メールから直接ディープリンクする必要がある(かなり一般的な)私のような人にとっては、次のことに注意する価値があります。

  • appScheme://を使用してメールを送信すると、リンクがGmailでフィルタリングされるため、正常に機能しません

  • appScheme://への自動リダイレクトはChromeによってブロックされています:Chromeではリダイレクトがユーザーの操作(クリックなど)と同期している必要があると思われます

  • appScheme://がなくてもディープリンクを実行できるようになりました。これは優れていますが、最新のプラットフォームと追加のセットアップが必要です。Android iOS


他の人々がすでにこれについて深く考えていることは注目に値します。Slackが「マジックリンク」機能をどのように実装しているかを見てみると、次のことがわかります。

  • 通常のhttpリンクを含むメールを送信します(GmailでもOK)
  • ウェブページにはappScheme://にリンクする大きなボタンがあります(ChromeでもOK)

9

あなたは問題を解決しようとするこのプラグインをチェックすることができます。missemisaやAlastairなどで説明されているのと同じアプローチに基づいていますが、代わりに隠しiframeを使用しています。

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


これを追加しましたが、アプリをインストールした後もAppstoreにリダイレクトされます。
カシム

9

@Alistairはこの回答で、ユーザーがアプリを開いた後にブラウザーに戻ることがあると指摘しました。その回答へのコメント者は、使用された時間の値はiOSのバージョンに応じて変更する必要があることを示しました。私たちのチームがこれに対処する必要があったとき、初期タイムアウトの時間値と、ブラウザーに戻ったかどうかを示す値を調整する必要があり、多くの場合、すべてのユーザーとデバイスで機能しないことがわかりました。

ブラウザに戻ったかどうかを判断するために任意の時間差しきい値を使用するのではなく、「pagehide」および「pageshow」イベントを検出することは理にかなっています。

何が起こっているのかを診断するために、次のWebページを作成しました。これは、主にコンソールロギング、アラート、またはWebインスペクター、jsfiddle.netなどの手法を使用すると、このワークフローに欠点があったため、イベントが展開するときにHTML診断を追加します。時間のしきい値を使用する代わりに、JavaScriptは「pagehide」および「pageshow」イベントの数をカウントして、それらが発生したかどうかを確認します。そして、最も強力な戦略は、1000の初期タイムアウトを使用することであることがわかりました(25、50、または100が他のユーザーによって報告/提案されたものではありません)。

これはローカルサーバーで提供でき、python -m SimpleHTTPServeriOS Safariなどで表示できます。

それを試すには、「インストールされているアプリを開く」または「アプリがインストールされていません」リンクを押します。これらのリンクにより、マップアプリまたはApp Storeがそれぞれ開きます。その後、Safariに戻って、イベントのシーケンスとタイミングを確認できます。

(注:これはSafariでのみ機能します。他のブラウザー(Chromeなど)では、pagehide / show-equivalentイベントのハンドラーをインストールする必要があります)。

更新: @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>

2

私はこのようなことをする必要があります私は次の解決策に行き着きました。

2つのボタンのあるページを開く特定のWebサイトのURLがあります

1)ボタン1はウェブサイトに移動します

2)ボタン2はアプリケーションに移動します(iphone / android電話/タブレット)アプリがインストールされていない場合(別のURLやアプリストアなど)、ここからデフォルトの場所にフォールバックできます

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>

私の要件にはこのタイプのコードが必要ですが、リンクを配置できません。要件:app1がインストールされている場合はリンク1に移動し、それ以外の場合はリンク2に移動します。誰か助けてくれますか?
SFDC_Learner 2016年

ユーザーが最初にウェブを選択した場合に備えて、アプリのインストール時にCookieの設定を解除する必要があります。
チャーリーReitzel

1

いくつかの回答をコンパイルした後、次のコードを思いつきました。驚いたのは、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フィドル


-2

日付のソリューションは他のものよりもはるかに優れています。これはトゥイーターの例のように、50の時間を増やす必要がありました:

//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が開かれたときに自動終了するというアラートを表示しますが、とりあえずは今のところ良い解決策です!


1
@AkshatAgarwalこれは、7日後に投稿されたalastairと同じソリューションであるため
albanx

-5

これらのすべてを読んだわけではありませんが、iframeを使用してソースを「my app:// whatever」に追加している可能性があります。

次に、ページの設定された間隔で404かどうかを定期的にチェックします。

Ajax呼び出しを使用することもできます。404応答の場合、アプリはインストールされていません。


これは目覚めの解決策ではありません。
Andrey M.
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.