2011-09-27 183 views
16

我有我的網頁,如果它沒有安裝應用程序,它可以打開應用程序(如果它安裝)或指向應用程序商店。 如果安裝了應用程序(我稱之爲「MYAPP://」),這一切都有效。但是,如果未安裝應用程序,Safari會顯示錯誤消息「無法打開URL」,就是這樣。有沒有辦法從JScript中禁用該消息,或者有另一種方法可以從JScript中找出安裝應用程序(而不是點擊應用程序URL)?iPhone瀏覽器:檢查是否從瀏覽器安裝iPhone應用程序

給主持人:我看到有人問similar question和主持人錯誤地標記爲重複。請理解這個問題是關於從瀏覽器中完成的。

發現有些合適的解決方案here

順便說一句,如果有人感興趣的是如何做同樣的事情爲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"; 
    } 
    }); 

回答

0

我認爲你仍然可以使用應用程序的網址作爲測試。嘗試在try...catch塊包裝它,

try { 
    //run code that normally breaks the script or throws error 
} 
catch(e) { 
    //do nothing 
} 
4

這裏是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解決方案。

+0

這裏是iOS和Android應用重定向一個完整的JS例如:https://gist.github.com/FokkeZB/6635236#file-all-in-one-php – Justin

0

我已經合併了一些東西,並使用下面的代碼來檢查它是否是iOS設備,然後使用chazbot中的try/catch方法。不幸的是,該設備仍然向用戶彈出一個彈出框,說該地址是無效的......任何人都知道這是否是嘗試在「嘗試」塊中打開無效URL的預期行爲?

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 
    } 
12

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觸發。

+0

謝謝,這是最好的解決方案,我'已經看到。與其他人一樣,如果未安裝目標應用程序,則iOS 8會在打開網頁之前提供「無效地址」消息。這只是選擇任何一個選項,並做到這一點。現在,讓它在Android上工作..! – JoLoCo

+0

祝你好運。每個瀏覽器都不一樣。鉻意向vs標準瀏覽器vs facebook webview vs twitter webview vs pinterest。這就是我每天在分店做的 –

+0

是的,這是一個真正的雷區,我發現了!如果我有任何重大突破,我會在這裏發佈它們... – JoLoCo

0

有幾件事情可以改善其他答案。從iOS 9開始,鏈接可以在UIWebViewSFSafariViewController中打開。你可能想要以不同的方式處理它們。

SFSafariViewController跨應用程序和內置Safari共享Cookie。因此,在您的應用中,您可以通過SFSafariViewController發出請求,該請求會設置一個表示「我的應用已安裝」的cookie。例如,你打開你的網站,要求你的服務器設置這樣的cookie。然後,當您收到SFSafariViewController的請求時,您可以檢查該cookie,如果找到該cookie,並將其重定向至MYAPP://,或者如果不存在,則重定向至應用商店。無需打開網頁並執行javascript重定向,您可以從服務器上執行301。像MessagesSafari這樣的應用共享這些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那裏做到這一點,那不會發生),但這就是我們得到的!

您可以從您的服務器區別於SFSafariViewControllerUIWebView,因爲他們有不同的用戶代理頭:在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 

其他注意事項:

    在第一種方法
  • ,你可能要處理卸載的:如果用戶卸載你的應用程序,你仍然有一個cookie,指出應用程序是有但事實並非如此,所以您最終可能會收到"Can not open URL"消息。我已經通過最終沒有打開的應用程序(這我知道,因爲在每一個應用程序打開的,我這個復位失敗嘗試的cookie)
  • 在第二種情況下,試了幾次之後,除去該cookie處理它,但目前還不清楚如果你最好使用setIntervalsetTimeout。超時的問題在於,如果在提示符打開時觸發,它將被忽略。例如,如果您打開Messenger的鏈接,當iframe嘗試加載您的應用程序時,操作系統會詢問您「離開Messenger?您即將打開另一個應用程序」。如果在超時500毫秒內沒有任何響應,超時中的重定向將被忽略。
  • 最後即使UIWebView是沙箱,你可以給它一個cookie來識別它,通過它在你的深層鏈接,而這個ID保存爲您的應用程序打開時,在你的服務器對應的設備與應用。下一次,如果您在來自UIWebView的請求中看到這樣的cookie,則可以檢查它是否與已知設備匹配,並像以前一樣直接與301重定向。
相關問題