音樂小程序開發(fā)名字(音樂小程序研究意義)

副標(biāo)題
2023-06-15 18:42:06 作者:網(wǎng)絡(luò)來源:網(wǎng)絡(luò)

  原文音樂小程序開發(fā)名字:http://www.jianshu.com/p/4ef3d3737661?hmsr=toutiao.io&utm_medium=toutiao.io&utm_source=toutiao.io

  作者:故胤道長

  在 iOS 開發(fā)中,寫一個(gè) App 很容易,但是要寫好一個(gè) App,確是要下另一番功夫。首先,我們來看一個(gè) App 的開發(fā)要求:

  寫一個(gè) App,顯示出 Spotify 上 Lady Gaga 相關(guān)的所有音樂專輯,相關(guān)信息可以通過以下網(wǎng)址查到:

  https://api.spotify.com/v1/search?q=lady+gaga&type=album

需求分析

  首先拿到開發(fā)要求,最重要的是明確開發(fā)細(xì)節(jié)。這里面有很多我們不清楚的地方需要與產(chǎn)品經(jīng)理和設(shè)計(jì)師交流:顯示是要用 TableView 還是 CollectionView?每個(gè)音樂專輯的哪些信息需要顯示?如果專輯數(shù)量過多,我們優(yōu)先顯示哪些專輯?這個(gè) App 除音樂小程序開發(fā)名字了顯示信息以外,還需要哪些拓展功能?這個(gè)產(chǎn)品的大小是否有要求?需要多少天完成?

  經(jīng)過討論之后,大家的一致意見是做個(gè)如下的 App:

  LadyGaga

  于是我們就清楚了,是要做一個(gè) tableView,每個(gè) Cell 對(duì)應(yīng)一個(gè)專輯信息,左邊是圖片,右邊是專輯名。點(diǎn)擊 Cell,可以看到相應(yīng)的專輯大圖。

  構(gòu)建架構(gòu)

  首先這個(gè) App 比較簡(jiǎn)單,我們只要用最基本的 MVC就可做好。

Model 部分:

  只需要一個(gè) Model, 為 Album,對(duì)應(yīng)每一個(gè)專輯的信息;

View 部分:

  主體的部分可以在 Storyboard 里面完成;

  最好單獨(dú)新建一個(gè) UITableViewCell 的子類,用來對(duì)應(yīng)設(shè)置專輯的UI;

ViewController 部分:

  其中一個(gè) ViewController 為 TableViewController,負(fù)責(zé)現(xiàn)實(shí)所有專輯的信息;

  另一個(gè) ViewController 負(fù)責(zé)展示 detail info,比如專輯的大圖;

Network 部分:

  負(fù)責(zé)從網(wǎng)絡(luò)上 fetch 專輯信息;以及根據(jù)專輯的圖片網(wǎng)址,fetch 圖片數(shù)據(jù);

  基本架構(gòu)

  細(xì)節(jié)實(shí)現(xiàn)

Network 部分:

  fetchAlbums 和 downloadImage 都用Apple 自帶的 URLSession 和 JSONserialization 就可以實(shí)現(xiàn),或者也可以用優(yōu)秀的第三方庫 AlamoFire。因?yàn)檫@個(gè) App 比較簡(jiǎn)單,AlamoFire 優(yōu)勢(shì)不明顯,且引入第三方庫會(huì)增加 App 的體積,故而推薦使用前者。基本上就是實(shí)現(xiàn)下面兩個(gè)函數(shù):

  funcfetchAlbums(with url: String, completion : @escaping (_ albums: [Album]?, _ error : NSError?) -> Void) funcdownloadImage(_ url: String) -> UIImage?

  對(duì)于第一個(gè)函數(shù) fetchAlbums,因?yàn)榫W(wǎng)絡(luò)請(qǐng)求是耗時(shí)耗力的工作,我們一般會(huì)將它們用后臺(tái)線程而非主線程(UI線程)來處理,這樣可以保持UI的流暢運(yùn)行。用閉包則是為了異步多線程完成后可以回調(diào),同時(shí) error 是為了監(jiān)視網(wǎng)絡(luò)請(qǐng)求是否出錯(cuò)。

  對(duì)于第二個(gè)函數(shù) downloadImage,最簡(jiǎn)單的方法是通過 url 拿到對(duì)應(yīng)的 data,然后通過相應(yīng)的 data 拿到 image。返回為 optional 的原因是有可能 URL 有問題或者網(wǎng)絡(luò)請(qǐng)求出錯(cuò),此時(shí)返回 nil。

  從API設(shè)計(jì)的角度來說,以上的downloadImage并不是最佳設(shè)計(jì)。最佳的設(shè)計(jì)是我們能知道哪里出錯(cuò)了,比如下面這樣:

  enumDownloadImageError: Error{ caseInvalidURLcaseInvalidData}funcdownloadImage(_ url: String)throws -> UIImage { guardlet aUrl = URL(string: url) else { throwDownloadImageError.InvalidURL } do { let data = tryData(contentsOf: aUrl) iflet image = UIImage(data: data) { return image } else { throwDownloadImageError.InvalidData } } catch { throwDownloadImageError.InvalidURL } }

音樂小程序開發(fā)名字(音樂小程序研究意義)

ViewController 部分:

  對(duì)于 AlbumsController,我們用到了代理模式(Delegate),即將 tableView 代理到了 AlbumsController 上。我們只要實(shí)現(xiàn)相應(yīng)的 dataSource 和 delegate 方法即可。其中對(duì)于 dataSource 而言,有兩個(gè)方法是必須實(shí)現(xiàn)的,它們是:

  functableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> IntfunctableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell

  同時(shí),AlbumsController 里面,還有兩個(gè)數(shù)組,一個(gè)用來裝專輯([Album]),一個(gè)用來裝圖片([UIImage?]),這樣我們只需下載數(shù)據(jù)一次,并將其存入相應(yīng)數(shù)組,之后就無需再次進(jìn)行相關(guān)的網(wǎng)絡(luò)請(qǐng)求了。也就是說,這兩個(gè)數(shù)組起到了緩存的作用。

  具體的實(shí)現(xiàn)是:首先在 viewDidLoad() 中請(qǐng)求服務(wù)器取出相應(yīng)的數(shù)據(jù)。之后根據(jù)專輯數(shù)量設(shè)定 TableView 的相應(yīng)行數(shù)。在具體的一行當(dāng)中,我們可以根據(jù) indexPath 確定相應(yīng)的專輯。根據(jù)相應(yīng)專輯的圖片 URL ,我們可以拿到相應(yīng)的圖片,之后緩存進(jìn)圖片數(shù)組。由于我們復(fù)用了 TableView 的 Cell,所以如果不緩存圖片而每次去進(jìn)行網(wǎng)絡(luò)請(qǐng)求,會(huì)因?yàn)檠訒r(shí)很嚴(yán)重而會(huì)造成圖片閃爍的后果。

  最后兩個(gè) ViewController 之間的跳轉(zhuǎn)可以用 navigationController 來實(shí)現(xiàn)。

View 部分:

  自定義 AlbumCell 可以保證 App 的擴(kuò)展性很好。同時(shí),為了處理有些專輯名字過長 Label 顯示不了的問題,可以用autoshrink 來處理。

  App 運(yùn)行流程

  優(yōu)化拓展

  上面的設(shè)計(jì)和實(shí)現(xiàn)比較理想化,現(xiàn)在我們要考慮一個(gè)邊界情況,假如網(wǎng)絡(luò)不穩(wěn)定,怎么辦?

  一個(gè)簡(jiǎn)單的解決方法就是,當(dāng)網(wǎng)絡(luò)好的時(shí)候把數(shù)據(jù)下載下來,存入 cache 和 storage 中,之后即使網(wǎng)絡(luò)中斷、App 崩潰,我們都能從 storage 中拿到相應(yīng)數(shù)據(jù)。

  這里引入外觀模式(Facade),創(chuàng)建一個(gè)新的 class 名為 LibraryAPI,提供兩個(gè)接口:

  funcgetAlbums(completion : @escaping (_ albums: [Album]?, _ error : NSError?) -> Void)funcgetImage(_ url: String) throws-> UIImage

  這里的方法跟之前 Network 的不同之處在于:getAlbums 方法會(huì)先嘗試從 storage 中取出相應(yīng)數(shù)據(jù),如果沒有,則去訪問 Network,之后再把從 Network 中拿到的值存入 storage 中。這里面的實(shí)現(xiàn)有點(diǎn)復(fù)雜,牽涉到兩大模塊和多線程操作,但是我們并不必關(guān)心方法內(nèi)部的實(shí)現(xiàn),而僅僅關(guān)心接口,這就是外觀模式的優(yōu)點(diǎn)。同時(shí),LibraryAPI 這個(gè) class 最好用單例模式(singleton),因?yàn)樗鼞?yīng)該被當(dāng)做是全局 API 被各個(gè) ViewController 來訪問,同時(shí)這樣設(shè)計(jì)也節(jié)省資源。

  優(yōu)化后的 App 流程

  另外一個(gè)優(yōu)化點(diǎn)在于,假如我們一開始拿到很多數(shù)據(jù) —— 例如10000 個(gè)專輯,那么我們?cè)撛趺床僮鳎?/p>

  正確的做法是分頁。我們可以先只拿20個(gè),顯示在 TableView 上。當(dāng)用戶快滑到底端的時(shí)候,我們可以再取下面20個(gè),然后我們總共有40個(gè)在內(nèi)存中可以顯示,以此類推。這樣做的好處是,我們無需下載所有的數(shù)據(jù),以最快、最流暢的方式布局 TableView,同時(shí)根據(jù)用戶的需求增加相應(yīng)的專輯數(shù)據(jù)。

  最后一個(gè)優(yōu)化點(diǎn)在于,假如用戶上下滑動(dòng)很快,我們?nèi)绾文軌蛴米羁焖俣燃虞d圖片?

  答案是用 operationQueue 來處理,當(dāng)前 cell 是可見的時(shí)候,我們就 resume 下載圖片的進(jìn)程,否則就 suspend。這樣保證了我們用有限的內(nèi)存和 CPU 去最高效的下載用戶需要、當(dāng)前要見的圖片。

  值得一提的是,大家還可以借鑒 ASDK 的思路來進(jìn)一步優(yōu)化程序。

  總結(jié)

音樂小程序開發(fā)名字(音樂小程序研究意義)

  本文從一個(gè)簡(jiǎn)單的 tableView App 說起,談?wù)摿碎_發(fā)一個(gè) App 的4個(gè)步驟:需求分析、構(gòu)建架構(gòu)、細(xì)節(jié)實(shí)現(xiàn)、優(yōu)化拓展。簡(jiǎn)單介紹了多線程和幾種設(shè)計(jì)模式,希望對(duì)大家有所幫助。

免責(zé)聲明:本站文章除注明外均來源于網(wǎng)絡(luò),如有版權(quán)或違規(guī)問題請(qǐng)聯(lián)系我們刪除!
我們猜你喜歡
主站蜘蛛池模板: 国产欧美久久一区二区三区| 日本最新免费二区三区| 国产美女自慰在线观看| 亚洲色图综合网站| jyzzjyzz国产免费观看| 男人的天堂在线免费视频| 婷婷亚洲综合一区二区| 免费在线黄色网| h小视频在线观看| 特区爱奴在线观看| 国自产拍亚洲免费视频| 亚洲欧美性另类春色| 2021国产在线视频| 欧美性大战XXXXX久久久√| 欧美疯狂性受xxxxx另类| 成人免费v片在线观看| 午夜国产在线观看| xxxxwww日本在线| 狠狠97人人婷婷五月| 国产黄a三级三级看三级| 亚洲国产欧美无圣光一区| sss欧美一区二区三区| 热99re久久精品精品免费| 国语对白一区二区三区| 亚洲成AV人片久久| xxxxx在线| 日韩在线视频精品| 国产亚洲精久久久久久无码| 中国老熟妇自拍HD发布| 男人肌肌捅女人肌肌视频| 国产色秀视频在线观看| 亚洲中文字幕无码久久综合网| 91黑丝国产线观看免费| 日日噜噜噜夜夜爽爽狠狠视频| 内射在线Chinese| 99re66热这里都是精品| 欧美人与牲动交xxxx| 国产在线午夜卡精品影院| 中文字幕一区视频| 男人j进女人p视频免费观看| 国产精品真实对白精彩久久|