用 SwiftUI 實(shí)現(xiàn)一個(gè)開源的 App Store
App Store 在 iOS 11 之前,App 排行榜一直是衡量開發(fā)者 App 活躍度的指標(biāo),但在 iOS 11 后蘋果弱化了榜單功能,改為了二級(jí)入口,導(dǎo)致查詢榜單困難,編者通過(guò)深入調(diào)研最終實(shí)現(xiàn)了一個(gè)查看 App 榜單、搜索、信息、發(fā)布生效等強(qiáng)大功能的開源 App。
一、前言
App Store 一直以來(lái)都是 iPhone 生態(tài)的最重要一環(huán),在初代 iPhone 商店,因?yàn)?App 比較少,當(dāng)時(shí)就有 Top 25 榜單:
然后在后續(xù)的 App Store 迭代中,排行榜(Top Charts)一直是一個(gè)主要的入口,新用戶基本都會(huì)從榜單下載 App,所以,榜單的重要性不容忽視。
直到 2017 年,雖然占了不到 30% 的手機(jī)份額,但 iPhone 的體量已經(jīng)非常大,App Store 應(yīng)用數(shù)量已經(jīng)達(dá)到 220 萬(wàn)。App Store 的展示和推薦,顯然滿足不了每天巨大的新 App,有越來(lái)越多的 App 希望得到關(guān)注;而另一方面,排行榜刷榜問(wèn)題一直存在;還有就是 App Store 的設(shè)計(jì)已經(jīng)滿足不了需求!比如更新(Updates) 標(biāo)簽功能單一,就是負(fù)責(zé)顯示需要更新的 App 列表。
所以,從 iOS 11 開始,蘋果將 AppStore 重新設(shè)計(jì),增加了 Today 和 Games 游戲標(biāo)簽入口,而排行榜列表放到了 Apps 標(biāo)簽的二級(jí)入口中。蘋果加強(qiáng)了自己的編輯團(tuán)隊(duì)推薦的App,在游戲和應(yīng)用標(biāo)簽分類的前面也加入了大區(qū)域的編輯推薦 App,如今已經(jīng)看不到榜單了。
而現(xiàn)在 iOS 15 中的 App Store 增加了更多的功能,比如產(chǎn)品頁(yè)優(yōu)化、自定產(chǎn)品頁(yè)、App 內(nèi)活動(dòng)(In-App Events)等,目的很明顯就是讓開發(fā)者增加活躍內(nèi)容,提升 App 日活和收入。
而排行榜功能,其實(shí)已經(jīng)不單單是一個(gè)榜單的作用,經(jīng)常這些年的沉淀,榜單基本已經(jīng)穩(wěn)定。比如大家看到的 App,常年不變,而沖到榜單的 App,會(huì)獲得更多的下載量。對(duì)于開發(fā)者來(lái)說(shuō),榜單可以用來(lái)預(yù)測(cè)應(yīng)用收入、使用量和下載量的一個(gè)重要指標(biāo)。對(duì)于用戶來(lái)說(shuō),發(fā)現(xiàn)一些有趣或者熱門的 App,依然是部分老用戶的習(xí)慣。
所以,編者希望通過(guò)實(shí)現(xiàn)一個(gè) App Store 排行榜,方便日常查看,同時(shí)查看信息,搜索或應(yīng)用發(fā)布狀態(tài)訂閱等功能,解決了非常多的痛點(diǎn)問(wèn)題。
二、效果展示
首先,我們先來(lái)介紹一下,目前 iAppStore 實(shí)現(xiàn)了那些功能。
iAppStroe[1] 是一款使用 SwiftUI 打造的蘋果商店工具類 App。
提供蘋果實(shí)時(shí)榜單查詢,包含 iOS 和 iPad 的熱門免費(fèi)榜、熱門付費(fèi)榜、暢銷榜,還有新上架榜、新上架免費(fèi)榜、新上架付費(fèi)榜等。
提供查詢 app 詳細(xì)頁(yè)面內(nèi)容、搜索 app、訂閱 app 狀態(tài)等功能。
支持蘋果所有國(guó)家和地區(qū)的商店,無(wú)需切換 Apple Id,即可查看!
2.1 排行榜
首先,App Store 的榜單有很多,包含 iOS 和 iPad 的熱門免費(fèi)榜、熱門付費(fèi)榜、暢銷榜,還有新上架榜、新上架免費(fèi)榜、新上架付費(fèi)榜等,我們都實(shí)現(xiàn)了這些榜單。另外,我們將 App Store 榜單的 UI 還原,同時(shí),也增加了更多的信息展示,比如 App 所屬分類等。
最重要的是,我們把所有國(guó)家和地區(qū)的商店,都集成在一個(gè)面板中,通過(guò)下拉列表選擇,實(shí)現(xiàn)快速切換榜單。
2.2 App 詳細(xì)頁(yè)
App 詳細(xì)頁(yè)面,把開發(fā)者最關(guān)心的參數(shù)顯示在最前面。另外,復(fù)制包含或者 App ID 是一個(gè)高頻的需求,App 描述和更新方案也高仿了 App Store 的效果。預(yù)覽區(qū)包含 iPhone 和 iPad 圖片。點(diǎn)擊可以顯示大圖,并且可以下載和分享大圖。
2.3 搜索
搜索區(qū),可以輸入關(guān)鍵字模糊搜索,或者 App ID 精準(zhǔn)搜索。另外,在右上角切換國(guó)家和地區(qū),顯示不同地區(qū)的 App 搜索。
2.4 應(yīng)用狀態(tài)訂閱
這個(gè)狀態(tài)訂閱是什么意思?就是可以監(jiān)聽 App 在商店的狀態(tài),舉例來(lái)說(shuō),App 發(fā)布了新版本,那么大概要多久才能在商店上顯示呢?所以,我們可以通過(guò)蘋果的接口,來(lái)定時(shí)的查詢 App 的狀態(tài),從而知道 App 什么時(shí)候生效。還有新 App 剛剛發(fā)布時(shí)、或者 App 需要下架了,什么時(shí)候才從商店消失等。
2.5 其它
為了方便開發(fā)者使用,App 列表長(zhǎng)按時(shí),會(huì)彈出操作列表,可以已經(jīng)復(fù)制 App 的信息或者快速打開 App Store 產(chǎn)品頁(yè),盡可能的快捷獲取內(nèi)容!另外,還支持暗黑模式,依然精美絕倫!切換圖標(biāo)可以選擇自己顯示的圖標(biāo)等。
大家想要什么功能,可以在評(píng)論區(qū)留言啊~
三、調(diào)研工作
接下來(lái),我們說(shuō)一下要實(shí)現(xiàn)以上功能,需要的 API 怎么調(diào)研出來(lái)的!通過(guò)大量的網(wǎng)頁(yè)檢索,最終測(cè)試后整理成有價(jià)值的列表:
3.1 榜單接口
查詢排行榜的 API 示例
以上內(nèi)容在蘋果公開的文檔,都沒(méi)有查詢到 API 文檔。但為蘋果網(wǎng)站到在一個(gè)頁(yè)面: Apple Services Performance Partners[6],其中一項(xiàng)服務(wù)叫:Enterprise Partner Feed Relational[7](企業(yè)信息流合作伙伴?),目前這個(gè)合作好像很難申請(qǐng)到。所以,相關(guān)的文檔鏈接都無(wú)法訪問(wèn)到,比如 affiliate.itunes.apple.com[8]。
那么以上鏈接中幾個(gè)參數(shù)類型,因?yàn)闆](méi)有文檔,所以調(diào)研梳理如下:
榜單類型
應(yīng)用分類
更多分類,參考蘋果網(wǎng)站的 HTML 標(biāo)簽:App Store[9]
國(guó)家或地區(qū)標(biāo)識(shí)
更多分類標(biāo)識(shí),參考蘋果網(wǎng)站的 HTML 標(biāo)簽:RSS Builder[10]
接口說(shuō)明
原本接口提供 200 條數(shù)據(jù)查詢,但 20221 年 9 月 2 日,蘋果接口調(diào)整后,大幅削減 App Store 應(yīng)用排行數(shù)據(jù)分享,從 1500 名降至 200 名。目前 AppStore 總榜、應(yīng)用、游戲榜、分類榜只能查看前 200 個(gè) App 的數(shù)據(jù)。
3.2 搜索接口
App 搜索接口比如簡(jiǎn)單,并且有官方文檔:
- iTunes Store API[11]
- iTunes Search API: Constructing Searches[12]
接口示例:
https://itunes.apple.com/search?term=斗羅大陸&country=cn&limit=200&entity=software
term 字段就是關(guān)鍵詞,country 字段是國(guó)家或地區(qū)的標(biāo)簽,跟上面的榜單接口是同一個(gè)。entity=software 固定為搜索軟件就好。詳細(xì)的使用,可以參考官方文檔,這里就不展開了。
3.3 App 詳細(xì)信息
查詢某個(gè) App 可以使用 lookup 接口,具體可以查看官網(wǎng)文檔:Lookup Examples[13]。
接口示例:
https://itunes.apple.com/cn/lookup?id=1558453472
3.4 App 評(píng)論內(nèi)容
查詢某個(gè) App 的用戶評(píng)論內(nèi)容,沒(méi)有在蘋果的文檔中找到,但是根據(jù)以上的調(diào)研,接口使用問(wèn)題不大。
接口示例:
https://itunes.apple.com/cn/rss/customerreviews/id=989673964/sortBy=mostRecent/json
地區(qū)、App Id、sortBy 字段,就可以搜索。如果需要分頁(yè)或者獲取更多,可以參考文末的鏈接。
四、開發(fā)思路
有了以上的 API 接口,就能實(shí)現(xiàn)我們的 App,這樣使用 SwiftUI 來(lái)構(gòu)建,現(xiàn)已開源:
- iAppStore - GitHub[14]
詳細(xì)的實(shí)踐過(guò)程就不在這樣講解了,因?yàn)?App 是工具類應(yīng)用,交互的內(nèi)容不多,所以并不是很復(fù)雜。當(dāng)然,使用 SwiftUI 構(gòu)建 UI 過(guò)程異常的快速,但是如果要調(diào)整 UI 細(xì)節(jié),確定需要花很多心思。比如,SwiftUI 還不支持 WebView,所以用 SFSafariViewController 橋接的 View 在 SwiftUI 組件中顯示會(huì)異常。
- How do I use SFSafariViewController with SwiftUI? - Stack Overflow[15]
另外,就是蘋果 API 的坑,接口返回的字段 im:id、im:bundleId,包含冒號(hào),讓人懷疑人生!最后,通過(guò)自定義鍵值名,解決了解析映射的問(wèn)題。詳細(xì),可以參考源代碼中 AppRank.swift[16] 類。
- struct IDAttributes: Codable {
- let imBundleID, imID: String
- // 自定義鍵值名
- enum CodingKeys: String, CodingKey {
- case imID = "im:id"
- case imBundleID = "im:bundleId"
- }
- }
綜上,如果是個(gè)人開發(fā)的 App,可以開始使用 SwiftUI 來(lái)開發(fā),畢竟原生的體驗(yàn)和原生的組件,用戶起來(lái)也很快樂(lè)。另外,不考慮支持低版本系統(tǒng),使用 SF Symbols[17] 提供的圖標(biāo),也非常的友好!
五、總結(jié)
iAppStore 從構(gòu)思到實(shí)現(xiàn),花了半個(gè)月的時(shí)間,期間調(diào)研接口和調(diào)試接口花了很多時(shí)間,網(wǎng)上依然看到很多人問(wèn)這些接口,相信很多開發(fā)者都不知道有這些接口,所以本文也算是一個(gè)答案總結(jié),希望這個(gè)問(wèn)題從此消失哈~ 最后,iAppStore 只是從編者需求來(lái)實(shí)現(xiàn)的一個(gè)產(chǎn)品,所以一定存在很多的問(wèn)題,但同時(shí)它是一個(gè)開源項(xiàng)目,所以,如果大家有興趣,一起來(lái)參與,增加更多有趣或者黑科技的體驗(yàn)吧!歡迎大家有任何想法或者建議,可以在評(píng)論區(qū)給我們反饋。也可以到 iAppStore - GitHub[18] 給我們 Star 鼓勵(lì)!感謝大家~
參考資料
[1] iAppStroe:
https://github.com/37iOS/iAppStore-SwiftUI
[2] RSS Builder: https://rss.applemarketingtools.com
[3] RSS Information:
https://www.apple.com/rss/
[4] Stack Overflow:
https://stackoverflow.com/questions/29997991/how-to-get-top-400-lists-from-itunes
[5] 鏈接:
https://www.kalman03.com/2015/05/04/tech/appstore_affiliates_resource/
[6] Apple Services Performance Partners:
https://affiliate.itunes.apple.com/resources/
[7] Enterprise Partner Feed Relational:
https://affiliate.itunes.apple.com/resources/documentation/itunes-enterprise-partner-feed/
[8] affiliate.itunes.apple.com:
https://affiliate.itunes.apple.com/resources/documentation/itunes-store-web-service-search-api.html
[9] App Store:
https://apps.apple.com/cn/genre/ios/id36
[10] RSS Builder:
https://rss.applemarketingtools.com/
[11] iTunes Store API:
https://affiliate.itunes.apple.com/resources/documentation/itunes-store-web-service-search-api/
[12] iTunes Search API:
Constructing Searches: https://developer.apple.com/library/archive/documentation/AudioVideo/Conceptual/iTuneSearchAPI/Searching.html#//apple_ref/doc/uid/TP40017632-CH5-SW1
[13] Lookup Examples:
https://developer.apple.com/library/archive/documentation/AudioVideo/Conceptual/iTuneSearchAPI/LookupExamples.html#//apple_ref/doc/uid/TP40017632-CH7-SW1
[14] iAppStore - GitHub:
https://github.com/37iOS/iAppStore-SwiftUI
[15] How do I use SFSafariViewController with SwiftUI? - Stack Overflow:
https://stackoverflow.com/questions/56518029/how-do-i-use-sfsafariviewcontroller-with-swiftui
[16] AppRank.swift:
https://github.com/37iOS/iAppStore-SwiftUI/blob/main/iAppStore/Models/AppRank.swift
[17] SF Symbols:
https://developer.apple.com/sf-symbols/
[18] iAppStore - GitHub:
https://github.com/37iOS/iAppStore-SwiftUI