YouTubeやマップなどのiPhoneアプリにhttp +ドメインベースのURLスキームを登録することはできますか?


223

iOSで、ドメインにあるURL(例:http : //martijnthe.nl)を、アプリが電話にインストールされている場合は常にアプリで開き、そうでない場合はMobile Safariで開くようにしたいと考えています。

これに対して一意のプロトコルサフィックスを作成し、Info.plistに登録することは可能だと読みましたが、アプリがインストールされていない場合、Mobile Safariはエラーを出します。

回避策は何ですか?

1つのアイデア:

1)デスクトップブラウザで開くhttp:// URLを使用し、ブラウザを介してサービスをレンダリングする

2)User-Agentを確認し、Mobile Safariの場合はmyprotocol:// URLを開いて(試行)してiPhoneアプリを開き、モバイルiTunesを開いてアプリのダウンロードを試みて失敗した場合に備えます。

これがうまくいくかどうかわからない...提案ですか?ありがとう!


4
ニューヨークの地下鉄では、Boingoによるwifiがあり、彼らが推奨するアプリケーションをダウンロードすると、WiFiに無料でアクセスできます。ダウンロードしたら、Safariに戻り、ブラウザがそれがインストールされているかどうかを検出して、アクセスを許可します。それがどのように行われているのでしょうか?
TommyG 2013年

2
Universal Linksは、エラーメッセージなしでこの使用例をサポートするようになりました。ここにあなたのドメインとアプリを設定する方法は次のとおりです。blog.branch.io/...
アレックス・オースティン

回答:


243

これを行うための最も煩わしくない方法は次のとおりだと思います。

  1. ユーザーエージェントがiPhone / iPod Touchのものかどうかを確認する
  2. appInstalledクッキーを確認する
  3. Cookieが存在し、trueに設定されている場合は、に設定window.locationしますyour-uri://(またはリダイレクトサーバー側で実行します)。
  4. Cookieが存在しない場合は、「サイト名にiPhoneアプリケーションがあることをご存知ですか?」を開きます。「はい、すでに入手しました」、「いいえ、試してみたい」、「一人にしてください」ボタンが付いたモーダル。
    1. [はい]ボタンをクリックすると、Cookieがtrueに設定され、リダイレクトされます。 your-uri://
    2. 「Nope」ボタンは「http://itunes.com/apps/yourappname」にリダイレクトし、デバイスでApp Storeを開きます
    3. 「Leave me alone」ボタンはCookieをfalseに設定し、モーダルを閉じます

私が試したけれども少し不格好であることがわかったもう1つのオプションは、Javascriptで以下を実行することです。

setTimeout(function() {
  window.location = "http://itunes.com/apps/yourappname";
}, 25);

// If "custom-uri://" is registered the app will launch immediately and your
// timer won't fire. If it's not set, you'll get an ugly "Cannot Open Page"
// dialogue prior to the App Store application launching
window.location = "custom-uri://";

16
素晴らしいソリューション。別のアプリケーションへのフォールバックの場合、エラーを表示せずにすぐにロードされます。したがって、itunes.comにフォールバックする代わりに... itms://phobos.apple.com / ...を使用して、ポップアップエラーを回避します。
jb。

47
問題window.location="custom-uri://成功した場合、フォールバックタイムアウトは強制終了されません。ユーザーがアプリからブラウザーに戻ったとき、タイマーはまだそこにあり、アプリストアリンクを起動します。これはユーザーエクスペリエンスの低下です。
ジョジョ

5
Cookieは#ios6でサンドボックス化されているようです。そのため、アプリケーションによって設定されたCookieに別のCookieからアクセスできません。(App WebUIやSafari Mobileなど)
Olivier Amblet 2013年

2
ユーザーがブラウザに戻ったときに元のタイムアウトが発生しないようにする方法を誰かが見つけましたか?(ジョジョが言及する賛成投票の問題)
cobolstinks

2
JoJoが言及する問題を解決するには、ユーザーがリンクをクリックしてから「長い時間」が経過していない場合にのみ、タイムアウトでコードを実行します。このソリューションを参照してください:stackoverflow.com/a/14751543/533420
kkara

95

フォールバックが別のアプリリンクである限り、JavaScriptでこれを行うことは十分に可能です。ネイサンの提案に基づいて構築:

<html>
  <head>
    <meta name="viewport" content="width=device-width" />
  </head>
  <body>

    <h2><a id="applink1" href="fb://profile/116201417">open facebook with fallback to appstore</a></h2>
    <h2><a id="applink2" href="unknown://nowhere">open unknown with fallback to appstore</a></h2>
    <p><i>Only works on iPhone!</i></p>    

  <script type="text/javascript">

// To avoid the "protocol not supported" alert, fail must open another app.
var appstorefail = "itms://itunes.apple.com/us/app/facebook/id284882215?mt=8&uo=6";

function applink(fail){
    return function(){
        var clickedAt = +new Date;
        // During tests on 3g/3gs this timeout fires immediately if less than 500ms.
        setTimeout(function(){
            // To avoid failing on return to MobileSafari, ensure freshness!
            if (+new Date - clickedAt < 2000){
                window.location = fail;
            }
        }, 500);    
    };
}

document.getElementById("applink1").onclick = applink(appstorefail);
document.getElementById("applink2").onclick = applink(appstorefail);

</script>
</body>
</html>

こちらからライブデモをご覧ください


7
リーと同意します。これはより簡単な解決策のようです。ただし、アプリが存在せず、アプリストアにリダイレクトされた場合でも、サファリからエラーメッセージが表示されます。
Jon

2
私はこのソリューションをAndroidとiOSの両方に使用しました。タイムアウト値を500から100に変更すると、iOSで[ページを開けません]ポップアップダイアログが表示されません。また、Androidではタイムアウトを50にする必要があることもわかりました
Rossini

14
「itms:」の代わりに「itms-apps:」を使用すると、1つのリダイレクトが保存され、アプリストアのアプリページが直接開きます。
ドイツのラトーレ2012年


9
アプリがインストールされておらず、アプリストアにリダイレクトする前に、サファリからの「ページを開けません」というエラーメッセージを回避する方法を知っている人はいますか?
davidk 2012


24

選択した回答がブラウザーアプリで機能することがわかりましたが、を実装するブラウザー以外のアプリで機能するコードに問題がありましたUIWebView

私にとっての問題は、Twitterアプリのユーザーがリンクをクリックして、Twitterアプリのから自分のサイトに移動することUIWebViewでした。次に、私のサイトのボタンをクリックすると、Twitterは空想になりwindow.location、サイトにアクセスできる場合にのみ完了しようとします。したがって、何が起こるかUIAlertViewというと、続行してよろしいですか?

私のソリューションにはiframeが含まれています。これによりUIAlertView、提示されることが回避され、シンプルでエレガントなユーザーエクスペリエンスが可能になります。

jQuery

var redirect = function (location) {
    $('body').append($('<iframe></iframe>').attr('src', location).css({
        width: 1,
        height: 1,
        position: 'absolute',
        top: 0,
        left: 0
    }));
};

setTimeout(function () {
    redirect('http://itunes.apple.com/app/id');
}, 25);

redirect('custom-uri://');

Javascript

var redirect = function (location) {
    var iframe = document.createElement('iframe');
    iframe.setAttribute('src', location);
    iframe.setAttribute('width', '1px');
    iframe.setAttribute('height', '1px');
    iframe.setAttribute('position', 'absolute');
    iframe.setAttribute('top', '0');
    iframe.setAttribute('left', '0');
    document.documentElement.appendChild(iframe);
    iframe.parentNode.removeChild(iframe);
    iframe = null;
};

setTimeout(function () {
    redirect('http://itunes.apple.com/app/id');
}, 25);

redirect('custom-uri://');

編集:

絶対位置をiframeに追加して、挿入されたときにページの下部にランダムな空白スペースがないようにします。

また、Androidでのこのアプローチの必要性を私が見つけていないことに注意することも重要です。を使用window.location.hrefすると問題なく動作するはずです。


1
できます!!おかげで、ようやくすべてのブラウザで機能するソリューションを見つけました。
コレラー2014

2
見つかった場合、これが最良のソリューションです。ありがとうございました。エラーポップアップはもうありません。
confile 14

1
@Timは、リンクがクリックされたときにこのコードを起動する場合は、リンクがクリックされたときに呼び出される関数でこのコードをラップします。
cnotethegr8 2014年

1
@ cnotethegr8私はそれを関数に入れてカスタムURLにリダイレクトしましたが、iTunesへのフォールバックはうまくいきません。これが私のコードです。何が欠けていますか?
Tim

1
他の誰かがiOS 9でこれで問題を抱えていましたが、Safariでは動作しなくなりました。
bgolson 2015年

20

iOS9で、Appleはついに特定のhttp://URL を処理するようにアプリを登録する可能性を導入しました:Universal Links

それがどのように機能するかの非常に大まかな説明:

  • http://アプリ内の特定のドメイン(Web URL)のURLを開くことに関心を宣言します。
  • 指定されたドメインのサーバーで、サーバーのドメインからURLを開くことに関心があると宣言したアプリで開くURLを指定する必要があります。
  • iOS URLロードサービスは、http://上記で説明したように、セットアップのURL を開こうとするすべての試みをチェックし、インストールされている場合は正しいアプリを自動的に開きます。最初にSafariを経由せずに...

これはiOSでディープリンクを行う最もクリーンな方法ですが、残念ながらiOS9以降でのみ機能します...


そしてそれはブラウザーの内側では機能しません... imessageやノートからのように外側でのみ機能します
Mik

9

ネイサンとJBの答えに基づいて再び構築:

余分なクリックなしのURLからアプリを起動する方法 リンクをクリックするという暫定的なステップを含まないソリューションを希望する場合は、以下を使用できます。このjavascriptを使用して、Django / PythonからHttpresponseオブジェクトを返すことができました。インストールされている場合はアプリが正常に起動し、タイムアウトの場合はアプリストアが起動されます。これがiPhone 4Sで機能するためには、タイムアウト期間を500から100に調整する必要があることにも注意してください。テストし、微調整して、状況に応じて適切に調整してください。

<html>
<head>
   <meta name="viewport" content="width=device-width" />
</head>
<body>

<script type="text/javascript">

// To avoid the "protocol not supported" alert, fail must open another app.
var appstorefail = "itms://itunes.apple.com/us/app/facebook/id284882215?mt=8&uo=6";

var loadedAt = +new Date;
setTimeout(
  function(){
    if (+new Date - loadedAt < 2000){
      window.location = appstorefail;
    }
  }
,100);

function LaunchApp(){
  window.open("unknown://nowhere","_self");
};
LaunchApp()
</script>
</body>
</html>

9
window.location = appurl;// fb://method/call..
!window.document.webkitHidden && setTimeout(function () {
    setTimeout(function () {
    window.location = weburl; // http://itunes.apple.com/..
    }, 100);
}, 600);

document.webkitHidden アプリが既に呼び出されており、現在のSafariタブがバックグラウンドに移動しているかどうかを検出することです。このコードはwww.baidu.comからのものです


このソリューションをテストしたところ、イベントは正しく配信されますが、「アドレスが無効であるため、Safariはこのページを開くことができません」というエラーダイアログが一瞬表示されることがわかりました。(1秒未満で自動的に閉じます)。
マイケルハンソン2013年

負荷にIFRAMEを使用appurlしてweburl、あなたの問題を解決することができ
zyanlu

1
@zyanlu:iFrameで試しました。まだサファリが同じエラーを示しています。
kunjus 2014年

5

アプリにカスタムスキームを設定iframeしてWebページにを追加するとsrc、iOSはアプリ内のその場所に自動的にリダイレクトします。アプリがインストールされていない場合、何も起こりません。これにより、アプリがインストールされている場合はアプリへのディープリンクを、インストールされていない場合はアプリストアにリダイレクトできます。

たとえば、Twitterアプリをインストールしていて、次のマークアップを含むWebページに移動すると、すぐにアプリに移動します。

<!DOCTYPE html>
<html>
    <head>
    <title>iOS Automatic Deep Linking</title>
    </head>
    <body>
        <iframe src="twitter://" width="0" height="0"></iframe>
        <p>Website content.</p>
    </body>
</html>

以下は、アプリがインストールされていない場合にアプリストアにリダイレクトするより完全な例です。

<!DOCTYPE html>
<html>
    <head>
    <title>iOS Automatic Deep Linking</title>
    <script src='//code.jquery.com/jquery-1.11.2.min.js'></script>
    <script src='//mobileesp.googlecode.com/svn/JavaScript/mdetect.js'></script>
    <script>
      (function ($, MobileEsp) {
        // On document ready, redirect to the App on the App store.
        $(function () {
          if (typeof MobileEsp.DetectIos !== 'undefined' && MobileEsp.DetectIos()) {
            // Add an iframe to twitter://, and then an iframe for the app store
            // link. If the first fails to redirect to the Twitter app, the
            // second will redirect to the app on the App Store. We use jQuery
            // to add this after the document is fully loaded, so if the user
            // comes back to the browser, they see the content they expect.
            $('body').append('<iframe class="twitter-detect" src="twitter://" />')
              .append('<iframe class="twitter-detect" src="itms-apps://itunes.com/apps/twitter" />');
          }
        });
      })(jQuery, MobileEsp);
    </script>
    <style type="text/css">
      .twitter-detect {
        display: none;
      }
    </style>
    </head>
    <body>
    <p>Website content.</p>
    </body>
</html>

最初の例の問題は、Mobile Safariに戻ると、Twitterが起動されていても「Twitterアプリがインストールされていません」と表示されることです。2番目の例と同じで、「Webサイトのコンテンツ」を表示します。アプリがインストールされている場合、別のコード(別のURLの読み込み、または2つのメッセージのいずれかを表示)を実行するコードが必要です。
mahboudz、2015年

1
はい、@ mahboudz、テキストを読んだ場合、それは自動的にアプリにリダイレクトできることを示すための単なる例です。
q0rban 2015年

次に、実際のWebサイトのコンテンツを示すより徹底的な例を示します。「Twitterアプリがインストールされていません」というテキストがわかりやすくなる場合は削除できます。
q0rban 2015年

ios 6はまだポップアップを表示します無効なURLのため、そのページを開くことができません
Andrei Shender

ここ@AndreiShenderは、iOSの使用状況の統計は、この記事の執筆時点では、次のとおりです。monosnap.com/image/8eXUcpEUi8fm94DiMZIdiIp4xUNaln.png iOSの8:72%、iOSの7:25%、以前のバージョン:3%
q0rban

4

解決策はこちらです。

ブラーとフォーカスを使用してブールシチエーションを設定する

//see if our window is active
window.isActive = true;
$(window).focus(function() { this.isActive = true; });
$(window).blur(function() { this.isActive = false; });

リンクを、次のようなものを呼び出すjqueryクリックハンドラーにバインドします。

function startMyApp(){
  document.location = 'fb://';

  setTimeout( function(){
    if (window.isActive) {
        document.location = 'http://facebook.com';
    }
  }, 1000);
}

アプリが開くと、ウィンドウにフォーカスがなくなり、タイマーが終了します。それ以外の場合は何も取得せず、通常のFacebookのURLをロードします。


提案ありがとうございました。「外部アプリケーションの起動」ダイアログは、ぼかしがフラグを非アクティブ化するのに十分であるように見えるという問題に直面しています。これは、アプリがインストールされていない場合でも発生します(デスクトップでiPhoneアプリを起動するためのリンクをクリックした場合など)。アイデア?
フラクソン

2

私の知る限り、OS全体にhttp:+ドメインURLを認識させることはできません。新しいスキームのみを登録できます(x-darkslide:私のアプリで使用しています)。アプリがインストールされている場合、Mobile Safariはアプリを正しく起動します。

ただし、アプリが「まだここにありますか?このリンクをクリックしてiTunesからアプリをダウンロードする」という方法でアプリがインストールされていない場合に対処する必要があります。あなたのウェブページで。


2
これはもう正しくありません。iOS9と最近のAndroidバージョンでは、特定のhttpURL をリッスンするようにアプリを登録できます
severin

0

User-Agentを確認し、Mobile Safariの場合はmyprotocol:// URLを開いて(試行)してiPhoneアプリを開き、モバイルiTunesを開いてアプリのダウンロードを試みて失敗した場合に備えてください。

これは私には合理的なアプローチのように聞こえますが、2つ目の手段としてモバイルiTunesを開くことができるとは思いません。私はあなたがどちらかを選ぶ必要があると思います-あなたのアプリまたはiTunesにリダイレクトしてください。

つまり、myprotocol://にリダイレクトし、アプリが電話上にない場合、iTunesにリダイレクトする2度目のチャンスはありません。

最初に(iPhoneに最適化された)ランディングページにリダイレクトし、ユーザーにクリックしてアプリに移動するオプションを提供するか、アプリがない場合はアプリを取得するように調整することができますか?しかし、そこで正しいことを行うのはユーザーに依存することになります。(編集:Cookieを設定できるので、これは初めてのものですか?)


1
それは間違っている。ページを開けない(アプリがインストールされていない)というエラーが表示された場合でも、JSは実行されます。そのため、別のフォールバックソリューションにリダイレクトできます。
エリック

0

ポップアップの問題を解決しようとして、私はAppleがこの懸念を回避する方法を持っていることを発見しました。

実際、このリンクをクリックすると、アプリケーションをインストールした場合、そのアプリケーションに転送されます。それ以外の場合は、ポップアップなしでWebページにリダイレクトされます。


3
私はそのリンクがどのように機能しているかをかなり深く掘り下げました。そして、私が思いつくことができる最高のものは、それがまったくJavaScriptソリューションではないということです。Appleは、カスタムプロトコルを必要とせず、代わりにURL文字列に一致する特別なURLハンドラーをアプリに登録しているようです。送信したリンクは、303ですぐにここにリダイレクトされます。メールでそのリンクを自分に送信すると、リンクをクリックすると、AppStoreアプリがインストールされていれば直接起動することがわかります
Casey

とても興味深い。あなたが正しい:それをクリックすると、インストールされていればAppStoreアプリが表示されます。ただし、「休業日」までに一部のパラメータを削除すると、Safari内に表示されます。Appleは特別なURLスキームを登録できます...
Titignes、2011

@Titignes、アプリまたはWebページを開くためにこの方法について詳しく説明してください。そのようなURLを構築するためのパターンは何ですか?
Andrei Shender 2015
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.