最近工作中需要知道用戶的 iPhone 上都安裝了哪些應用炮车,所以查閱了一些資料酣溃。總的來說主要還是通過使用 Apple 提供的 - canOpenURL:
API 來測試相應 APP 的 scheme 是否有效來實現(xiàn)扛或。
如何知道某個 APP 支持的所有 scheme
很顯然碘饼,為了知道對應的 APP 是否在設備上,我們需要知道這個 APP 支持的所有 scheme(如果 APP 沒有定義任何自己的 scheme住涉,請看使用私有 API )钠绍。這里我總結(jié)了一下大概有兩種方法。
- 使用別人已經(jīng)整理好的scheme媳握。比如這個wiki頁面磷脯,里面收錄了一些比較有名的 APP 的 scheme争拐。當然還有這個網(wǎng)站,你可以在這里查詢 scheme 對應的 APP隘冲,你還可以幫助將你知道的 APP 的 scheme 添加進去绑雄,方便后面的人搜索。
- 自己動手查看 APP 的 scheme罗珍。主要分下面幾步:
- 獲取 IPA 包。這里你可以使用 iTunes 下載 APP蘸朋。 然后在
~/Music/iTunes/iTunes Media/Mobile Applications
這個目錄下可以找到 iTunes 為我們下載的 IPA 包扣唱。 - 將 IPA 包的擴展名改成 zip,這樣我們就可以解壓了炼彪。
- 解壓之后打開
Payload
文件夾正歼,右鍵擴展名為 app 的文件夾,選擇顯示包內(nèi)容
就可以查看到內(nèi)部的文件了 - 找到
Info.plist
文件喜爷,搜索CFBundleURLSchemes
就可以看到這個 APP 給自己定義的 scheme 了旭咽。
- 獲取 IPA 包。這里你可以使用 iTunes 下載 APP蘸朋。 然后在
如何使用 -canOpenURL:
iOS9 上面出于對用戶隱私的保護穷绵,開發(fā)人員不能像以前一樣隨便 -canOpenURL:
了。 通常在 iOS9 及以后版本的系統(tǒng)中勾缭,使用 -canOpenURL:
分為如下幾步目养。
- 點擊工程文件,選擇相應的
Target
幻梯,點擊Info
選項努释,展開Custom iOS Target Properties
- 找到或者添加
LSApplicationQueriesSchemes
到屬性列表中。同時在這個數(shù)組下面添加相應的 scheme
當然你也可以直接編輯項目的 Info.plist
文件煞躬,在 LSApplicationQueriesSchemes
鍵下面添加你在 APP 中會使用到的 scheme。
通過將 scheme 添加到白名單中在扰,我們就可以在代碼中使用 -canOpenURL:
來測試對應 scheme 的 APP 是否被安裝雷客。如果你沒有將 scheme 添加到白名單中卻在 -canOpenURL:
中使用了搅裙,你的查詢會失敗,同時控制臺會打印類似下面這樣的信息:
-canOpenURL: failed for URL: "fb://" - error: "This app is not allowed to query for scheme fb"
-canOpenURL: failed for URL: "twitter://" - error: "This app is not allowed to query for scheme twitter"
正常的輸出是這樣的(如何 -canOpenURL:
測試 scheme 失敗的話,成功的話控制臺默認不會有任何輸出
):
-canOpenURL: failed for URL: "fb://" - error: "(null)"
這里或許有個疑問就是為什么這樣就能保護用戶隱私呢甥啄? 畢竟我們可以添加很多的我們會測試的 scheme 到白名單中炬搭。 如果你無限制的添加 scheme 到白名單中, app store 審核時候可能會覺得你濫用了這個機制融虽,從而不讓你的 APP 審核通過灼芭。
要注意的是使用 iOS8 sdk 編譯的代碼跑在運行 iOS9 系統(tǒng)的設備上是沒有問題的,但是一個 APP 可以測試的 scheme 有數(shù)量的限制巍佑,大概是50條寄悯。
關于 iOS9 上的 -openURL:
我測試了一下猜旬,在沒有添加 scheme 到白名單的情況下脆栋,使用 -openURL:
會默認打開相應的應用,同時該函數(shù)返回 true
(如果設備安裝了)椿争,否則函數(shù)返回 false
(也不會有任何提醒)。 而在添加了 scheme 到白名單的情況下丘薛,使用 -openURL:
會彈窗提示(有時候又沒有彈窗??邦危,難道是第一次選擇是跳轉(zhuǎn)以后后面都默認跳轉(zhuǎn)嗎舍扰? 從這點可以看出 Apple 這個 API 做的用戶體驗并不好)用戶是否需要打開相應的應用边苹,選擇是則打開裁僧,否則不打開,同時函數(shù)也會正確的返回 true
或者 false
<a name="private-api"></a>使用私有 API
私有 API 也就是 Apple 提供的 iOS SDK 中沒有暴露給外部的接口類和方法茬底。我們知道 OC 函數(shù)調(diào)用是運行時決定的获洲,利用這個特性,通過一些手段獲取到 Apple 的一些私有 API 的類名和方法名最爬。我們就可以很容易的使用這些 API门岔。對于本文主題寒随,GitHub 上有一個很好的例子,大家可以下載這個 demo妻往,了解如何使用私有 API 來獲取設備上支持的所有 scheme蒲讯,以及所有安裝的 APP 信息。
需要注意的是局嘁, 如果你在項目中使用了私有 API晦墙,那么你可能需要做一些函數(shù)調(diào)用方式上的處理,以避免在 APP 審核的時候被發(fā)現(xiàn)導致被拒但指。
關于私有 API 更多的介紹可以看這個 StackOverflow 回答 What exactly is a private api and why will apple reject an ios app if one is us
關于 Apple 是如果檢測應用是否使用了私有 API可以看這里 How does apple know you are using private api