有很多產(chǎn)品都是同時(shí)具備 Web 端和 App 端的形態(tài)。比如簡(jiǎn)書(shū),經(jīng)??梢栽谂笥讶吹絹?lái)自這里的分享,所以在傳播方面就很倚重 Web,然后在頁(yè)面上對(duì) App 進(jìn)行關(guān)聯(lián),提高導(dǎo)流轉(zhuǎn)化率。
目標(biāo)效果
最終實(shí)現(xiàn)的效果有以下三條:
- 若用戶(hù)未安裝 App,則顯示 App 信息,方便用戶(hù)點(diǎn)擊安裝。
- 若用戶(hù)已安裝 App,則自動(dòng)調(diào)起并在 APP 中進(jìn)行顯示。
- 若用戶(hù)已安裝 App,但仍然切換到瀏覽器閱覽,則提供手動(dòng)點(diǎn)擊打開(kāi) App 的方式。
本文將介紹如何在自己的產(chǎn)品中達(dá)到上述效果。
由于 Web 頁(yè)面是在瀏覽器中顯示的,所以能否實(shí)現(xiàn)功能和用戶(hù)所用具體瀏覽器相關(guān)。
本文以 iOS Safari 及 Android Chrome 為主,會(huì)提及微信的內(nèi)置瀏覽器,但不再不包含其他。
先來(lái)看效果圖

效果 2 的自動(dòng)打開(kāi) App 在上圖中并未體現(xiàn)
iOS
Smart App Banners
這是 iOS 6 之后 Safari 默認(rèn)支持的功能,可以實(shí)現(xiàn)效果 1 和 3,請(qǐng)參見(jiàn)上圖前兩幅。
具體實(shí)現(xiàn)方法很簡(jiǎn)單,只需要在 Web 中加入一條 meta 信息指定 App ID 和 URL即可。
<meta name="apple-itunes-app" content="app-id=888237539, app-argument=http://jianshu.com/p/d7ae65ccac3e">
點(diǎn)擊打開(kāi)后具體行為(顯示文章)及數(shù)據(jù)(文章 ID)可以通過(guò) app-argument 指定,然后在此方法中處理 application:openURL:sourceApplication:annotation:[1]
推薦一個(gè)第三方庫(kù) HHRouter,很方便即可將 URL 映射至 View Controller
具體過(guò)程及原理可參考官方文檔說(shuō)明,此處不再詳述。
要注意此功能在模擬器中無(wú)法生效
另外如果 App 是首次要實(shí)現(xiàn)此功能,實(shí)機(jī)也無(wú)法觸發(fā)第二幅圖的效果
等包含此功能的版本在 Apple Store 發(fā)布之后,才能看到第二幅圖的效果
Universal Links
這是從 iOS 9 之后才支持的功能,可以實(shí)現(xiàn)效果 2,各位自己分享本文到微信中,然后選擇在 Safari 中打開(kāi)即可看到。
實(shí)現(xiàn)上,首先在 Server 創(chuàng)建『apple-app-site-association』文件(需支持 HTTPS[2] 訪(fǎng)問(wèn)),記載哪些 Web 路徑應(yīng)該在 App 中打開(kāi),例如簡(jiǎn)書(shū)的 https://jianshu.com/apple-app-site-association,可見(jiàn)支持文章、專(zhuān)題、用戶(hù)信息、文集這四種頁(yè)面。
{
"applinks": {
"apps": [],
"details": [
{
"appID": "KS7QAPBMXA.com.jianshu.Hugo",
"paths": [ "/p/*", "/collection/*", "/users/*", "/notebooks/*" ]
}
]
}
}
接下來(lái)在設(shè)置 App 中支持域名
啟用 Associated Domains 服務(wù)
登錄開(kāi)發(fā)者中心,在 Identifiers -> App IDs 下找到對(duì)應(yīng) ID enable 即可。關(guān)聯(lián)域名
用 Xcode 打開(kāi)項(xiàng)目,在 TARGETS -> Capabilities 下找到 Associated Domains 項(xiàng)目,填入域名即可。
最后,App 中實(shí)現(xiàn) application:continueUserActivity:restorationHandler: 就好。
詳情可參考官方文檔說(shuō)明,另外提供一個(gè)官方工具可以檢測(cè)某網(wǎng)址是否支持 Universal Links 等功能。
自定義 URL Schemes
也可以利用來(lái)打開(kāi) App,例如簡(jiǎn)書(shū)點(diǎn)擊 打開(kāi)應(yīng)用 按鈕就會(huì)調(diào)用 jianshu:// 來(lái)嘗試打開(kāi)自己的 App,請(qǐng)參見(jiàn)上圖第三幅。
和 Universal Links 區(qū)別是,這個(gè)不能自動(dòng)打開(kāi) App,會(huì)給用戶(hù)彈出一個(gè)確認(rèn)框,經(jīng)用戶(hù)同意才可以。
實(shí)現(xiàn)上也很簡(jiǎn)單,在 Info.plist -> URL types 創(chuàng)建 item 定義 CFBundleURLName 及 CFBundleURLSchemes 即可。前者不重要,一般用域名的反序,后者即是自定義的 Schemes。
接下來(lái) App 里實(shí)現(xiàn)此方法 application:openURL:sourceApplication:annotation:[1]
Android
Smart App Banner
很遺憾官方并沒(méi)有提供類(lèi)似于 iOS 的同等功能,不過(guò)這款 jQuery 插件[3] 大致可以模擬出該效果。
當(dāng)然也需要在 Web 中加入 meta 來(lái)標(biāo)志 App 的包名
<meta name="google-play-app" content="app-id=com.jianshu.haruki">
雖然 name 是 google-play-app,不過(guò)當(dāng)用戶(hù)點(diǎn)擊查看 App 的按鈕后,各種商店 App 都可以響應(yīng),所以只要 App 在各大商店上架就可以正常使用。
該插件沒(méi)法判斷用戶(hù)是否已經(jīng)安裝了 App,無(wú)法實(shí)現(xiàn)圖中第 2 幅的效果
Intent Filters
已安裝 App 的狀態(tài)自動(dòng)打開(kāi)的功能,需要 App 自己響應(yīng)自家域名的 http/https。
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="http" android:host="jianshu.com" />
</intent-filter>
這里推薦一個(gè)開(kāi)原庫(kù) ActivityRouter,可以用注解的方式配置 Activity 自動(dòng)響應(yīng) Web URL。
@Router("http://jianshu.com/p/:postId")
public class PostActivity extends Activity {
...
}
當(dāng)訪(fǎng)問(wèn)自家的網(wǎng)頁(yè)時(shí),系統(tǒng)會(huì)提示用戶(hù)是否用 App 打開(kāi),如果用戶(hù)選擇了『總是』的話(huà),以后就可以實(shí)現(xiàn)自動(dòng)打開(kāi)了。
自定義 URL Schemes
手動(dòng)點(diǎn)擊打開(kāi)打開(kāi) App 的話(huà),觸發(fā) intent:// 的調(diào)用即可(例如放在 a 標(biāo)簽中)。不過(guò)要注意必須由用戶(hù)手勢(shì)觸發(fā),否則調(diào)用無(wú)效。
實(shí)現(xiàn)方式類(lèi)似上方的自動(dòng)打開(kāi),不過(guò) intent 調(diào)用需要遵循一定格式,詳見(jiàn)官方文檔
window.location = "intent://notes/d7ae65ccac3e/#Intent;scheme=jianshu;package=com.jianshu.haruki;end"
App 側(cè)首先配置響應(yīng)自定義 scheme
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="jianshu" />
</intent-filter>
邏輯仍然可以用 ActivityRouter 很方便的實(shí)現(xiàn)。
如果用戶(hù)沒(méi)有安裝 App 時(shí),Chrome 會(huì)嘗試打開(kāi) Google Play,可能會(huì)對(duì)用戶(hù)造成一點(diǎn)困擾。
-
iOS 9 之后請(qǐng)使用 application:openURL:options: ? ?
-
這個(gè)使用目前流行的 Let's Encrypt 可以很方便實(shí)現(xiàn) ?
-
這款插件還同時(shí)支持 Windows Phone 以及 iOS 4/5,雖然沒(méi)啥人用 ?