通用連結(Universal Links)實踐筆記
一、實現大致思路
前提條件:
1. 支援https的伺服器
我使用的是阿里雲伺服器,ssl證照使用的是pianyissl.com的測試證照,可以免費使用三個月。配好證照,使用tomcat、nginx部署環境。
2. 伺服器繫結域名
3. 在伺服器根目錄上傳apple-app-site-association檔案
效果需要滿足訪問https:domain.com/apple-app-site-association 能夠下載或者開啟json內容
二、開發中我的問題
微信中點選開啟App網頁按鈕,想一個連結同時相容iOS 9以上及以下。iOS9以上,點選連結直接進入app指定頁面,iOS9以下進入應用寶下載頁面。開發中遇到問題,微信網頁內使用js沒有找到判斷手機是否安裝了app,導致在未安裝app時候點選連結進入404頁面,展示很不好。開始嘗試將404頁面重定向到應用寶下載app頁面,這樣又出現app安裝時點選開啟按鈕無法啟動app。後來想了一個方法,終於解決了問題。
a. 初始通用連結這樣寫:
https://joeychang.me/s?name=test&url=http://baidu.com&type=2
這樣可以實現通用連結,但是在iOS9以下及未安裝app情況下,連結無效。
b. 後改成這樣https://joeychang.me/s.html?name=test&url=http://baidu.com&type=2
在https://joeychang.me/s.html檔案執行js重定向,使用者點選這個頁面,跳轉到應用寶下載頁。這樣可以相容iOS9以下及未安裝app情況。
c. 再後來,為了和安卓統一,引數格式定為
http://blog.joeychang.me/index.html?params={“type”:”3”,”url”:”http://baidu.com“,”name”:”test”}
進入index.html這個頁面,js方法抓取到params,點選頁面內開啟按鈕,將引數傳遞給app,從未進入特定頁面。
d. 為了處理特殊符號,將params={“type”:”3”,”url”:”http://baidu.com“,”name”:”test”}進行[urlEncode](http://tool.chinaz.com/tools/urlencode.aspx
)之後再拼接到http://blog.joeychang.me/index.html?之後,生成長連結,再[短連結處理](http://dwz.wailian.work/
)生成短連結。短連結即可分享。從iOS 9.2開始,在相同的domain內Universal Links是不work的,必須要跨域才生效,我們實測值需要跨子域名即可,比如 m.domain.com 跳轉 o.domain.com 是可以觸發跳轉App。
這個又踩到坑了,在這裡費了好長時間,最後還是和同事商討才找到的答案。
apple-app-site-association檔案,s.html放在joeychang.me伺服器根目錄,是為同一個域名內,而開啟app.html為微信內喚醒app過渡網頁,這個放在blog.joeychang.me域名下,才成功跳轉。開始同樣放在joeychang.me域名下,怎麼也啟動不了,險些要放棄開發,後來換了下域名,問題解決。坑死人。
三、幾點注意:
apple-app-site-association檔案不能帶字尾,務必把”.json”的字尾去掉!有些人的電腦是隱藏檔案字尾的,這要格外注意;
apple-app-site-association要傳到域名根目錄或者/apple-app-site-association目錄下;
如果想測試這個功能,可以讓後臺搭一個測試伺服器,並繫結域名,然後iOS這邊通過host訪問域名就可以了。注意”applink:”後面寫的一定是域名,不能是IP;
抓包的結果顯示,網路順暢的情況下,應用會在在剛安裝(不是開啟)的時候會去applink中的地址下載apple-app-site-association檔案,所以如果需要測試,請保證網路通暢;
當所有都準備好,需要測試該功能的時候,只需要在記事本或簡訊中輸入App能識別的連結(例如:https://www.joeychang.me/s/oaze4qfl97hksef/IMG_0019%20%281%29.png?dl=0 ),然後直接點選或是長按就可以了,直接點的效果是跳轉到你的App,然後右上角是“去網頁”的箭頭,長按的效果是彈出的選單中第二項是“在’XXX’中開啟”,這也代表著成功。直接在Safari中輸入連結是無效的,必須從一處跳入才可以(比如上一級網頁)。
蘋果有個網址(這裡)可以檢測你的apple-app-site-association是否是有效的,準備好了可以測試一下。
測試的時候,建議使用dev證照打包,之後安裝到手機上測試功能。未安裝應用的情況下直接在手機上跑好像也是可以的,因為抓到過請求。
四、使用apple 的測試介面測試出現的問題:
校驗時出現問題 Applinks validator “domain missing from entitlement”,查了下資料,有這樣說的:
This is the “App Search API Validation Tool”, not the “Universal Links Validation Tool” (which doesn’t exist from Apple). The results from this tool have no connection to whether Universal Links work or not.
This tool causes a lot of confusion, because domains that definitely work with Universal Links (https://google.com, https://jet.com, for example) still throw errors. Officially, it is comparing your website’s apple-app-site-association file to your app’s listing on the App Store, so if the version of your app that is publicly available does not yet have Universal Links entitlements, that will cause these errors. However, Universal Links will still work fine with local builds.
If your links are correctly opening your app, there is probably no need to worry.
我的實踐是,即使校驗不通過,只有配置檔案json格式正確,上傳目錄正確,就可以開啟應用。我出現的問題,apple-app-site-association內容,bundle Id中的teamId寫錯了,導致很長時間沒有找到出錯原因。後來對比了下蘋果開發者中心才發現問題所在。白白浪費了很多時間。
五、參考連結:
- Universal Links官方文件
- Universal Links – Make the Connection
- iOS Universal Links(通用連結) (很不錯的教程)
- 突破微信跳轉限制-Universal-Links那些坑
- 好文:iOS 9學習系列:打通 iOS 9 的通用連結(Universal Links)
六、附開啟app過渡頁.html示例原始碼
<!DOCTYPE html">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="viewport" content="width=device-width,minimum-scale=1.0">
<body bgcolor = "#FFEEDD">
<input type="text" id="acti">
<p>下載頁面<a href="javascript:;" onclick="open_iOS_App()">ios 點選連結</a></p>
</body>
<a href="" id="aaa"></a>
<script type="text/javascript">
var timeout;
function open_iOS_App() {
if (isWeiXin()) {
open_App();
}else{
open_App();
timeout = setTimeout('open_itunes()', 3000);
};
}
function open_Android_App() {
if (isWeiXin()) {
open_android_weixin();
}else{
open_App_Android();
};
}
function open_android_weixin() {
var acti = document.getElementById("acti").value;
var linkUrl = "xxxxxxxxxxxxx://utils?action=sendIntent¶ms=" + acti;
var yingyongbaoUrl = "http://a.app.qq.com/o/simple?pkgname=com.xxxx.xxxxx&android_schema="
+ encodeURI(linkUrl);
window.location = yingyongbaoUrl;
}
function open_App() {
var ver = (navigator.appVersion).match(/OS (\d+)_(\d+)_?(\d+)?/);
ver = parseInt(ver[1], 10);
if(ver<9)
{
if (isWeiXin()) {
open_weixin_App();
}else{
open_itunes();
}
} else{
var activity = document.getElementById("acti").value;
document.getElementById("aaa").href = "https://joeychang.me/s.html?params="+ encodeURI(activity);
// alert(document.getElementById("aaa").href);
// alert(activity);
document.getElementById("aaa").click();
}
}
function open_App_Android() {
var acti = document.getElementById("acti").value;
window.location = "intent://xxxxxxxxx?params="+ acti +"#Intent;package=com.xxxx.xxxxx;scheme=xxxxxxx;launchFlags=268435456;end;";
}
function open_itunes() {/* 開啟app store */
window.location="http://itunes.apple.com/cn/app/idxxxxxxxx";
}
function open_weixin_App() {/* 開啟騰訊應用寶 間接跳轉 */
var acti = document.getElementById("acti").value;
window.location="http://a.app.qq.com/o/simple.jsp?pkgname=com.xxxx.xxxxx&activity=" + acti;
}
/*
判斷是否是微信瀏覽器
*/
function isWeiXin(){
var ua = window.navigator.userAgent.toLowerCase();
if(ua.match(/MicroMessenger/i) == 'micromessenger'){
return true;
}else{
return false;
}
}
function linktoApp() {
var queryStr = decodeURI(window.location.search.substr(1));
var ua = navigator.userAgent.toLowerCase();
if (queryStr.indexOf("}") >= 0 && queryStr.indexOf("{") >= 0) {
var activity = queryStr.substring(queryStr.indexOf("{"), queryStr.lastIndexOf("}") + 1);
document.getElementById("acti").value = activity;
if (/iphone|ipad|ipod/.test(ua)) {
// IOS
} else if (/android/.test(ua)) {
// Android
open_Android_App();
} else {
// 其他瀏覽器
window.location="http://a.app.qq.com/o/simple.jsp?pkgname=com.xxxxxxx.xxxxxxxx";
}
} else {
document.getElementById("acti").value = "引數格式錯誤";
}
}
// 用js實現在載入完成一個頁面後自動執行一個方法
/*用window.onload呼叫myfun()*/
window.onload=linktoApp;//不要括號
</script>
</head>
<body>
</body>
</html>
相關文章
- Angular Universal 學習筆記Angular筆記
- IOS H5頁面透過universal-link(通用連結)開啟APPiOSH5APP
- IOS H5頁面通過universal-link(通用連結)開啟APPiOSH5APP
- [筆記]最佳實踐筆記
- Python 連結串列實踐Python
- 連結串列-雙向通用連結串列
- 易優CMS模板標籤links友情連結控制友情連結的開啟方式
- 連結串列-雙向非通用連結串列
- 人工智慧實踐:Tensorflow筆記:程式碼總結(2)人工智慧筆記
- 《Predict Anchor Links across Social Networks via an Embedding Approach》閱讀筆記ROSAPP筆記
- Universal播放器的原始碼學習筆記播放器原始碼筆記
- ThreadLoop實踐學習筆記threadOOP筆記
- 閱讀筆記與部落格連結筆記
- 013 通過連結串列學習Rust之實現連結串列的通用函式Rust函式
- 013 透過連結串列學習Rust之實現連結串列的通用函式Rust函式
- LVGL雙向連結串列學習筆記筆記
- Mybatis plus通用欄位自動填充的最佳實踐總結MyBatis
- 《Golang學習筆記》error最佳實踐Golang筆記Error
- 學習筆記專案實踐(python)筆記Python
- 【docker】Docker入門到實踐 筆記Docker筆記
- 「輕算賬」小程式實踐筆記筆記
- Redis筆記 — 連結串列和連結串列節點的API函式(三)Redis筆記API函式
- 解決 ln -s 軟連結產生的Too many levels of symbolic links錯誤Symbol
- 瀏覽器中喚起native app || 跳轉到應用商城下載(二) 之universal links瀏覽器APP
- 連結串列的概念、實踐和麵試題
- 一些Q複製實踐的連結
- 《Kafka入門與實踐》讀書筆記Kafka筆記
- 實體連結在小布助手和OGraph的實踐應用
- ✨如何實現一個通用的“劃詞高亮”線上筆記功能?✨?️筆記
- 0.去O過程實踐筆記-前言筆記
- 讀小程式效能優優化實踐-筆記優化筆記
- .NET Core學習筆記(7)——Exception最佳實踐筆記Exception
- Docker筆記(十三):容器日誌採集實踐Docker筆記
- 《Python開發簡單爬蟲》實踐筆記Python爬蟲筆記
- 《CMake實踐》筆記二:INSTALL/CMAKE_INSTALL_PREFIX筆記
- JavaScript設計模式與開發實踐筆記JavaScript設計模式筆記
- docker 筆記3 dockerfile語法及最佳實踐Docker筆記
- 2.3.2.2.1 Metadata Links
- Links, Symbolic or OtherwiseSymbol