iTunesMusic App developed note
在此簡單記錄一下開發過程遇到的問題與參考的資料,GitHub上有demo影片,這邊就不重複放囉~
App demo/GitHub:
在searchBar搜尋,下方會跳出相對應的結果,點擊play button會播放previewUrl music
APP content:
Defined static shared, call function by shared
Defined function with completion
Get API data, decode to JSON format
App function detail:
UISearchResultsUpdating:
URLComponents, URLQueryItem:
當QueryItem不只一項時,可以用component.queryItems來新增
var queries = [String:String]()
queries["term"] = "告五人"
queries["media"] = "music"
queries["country"] = "tw"...var component = URLComponents(url: searchUrl, resolvingAgainstBaseURL: true)!
component.queryItems = queries.map{
URLQueryItem(name: $0.key, value: $0.value)
}
completion & Result type:
使用Result type可以讓Error handling更完善
下面以fetchImageWithURL為例子,completion(.success(image))傳出成功的image,接收時先用switch case確認result,若是成功就可以取得image
click cell’s button to do something:
若是在xib拉button action會無法判斷是哪個cell button被觸發,所以先做click cell and play music
查了發現以下方法可行,已修正(demo影片未更新)
cell button edit tag and addTarget, click button will trigger #selector func.
Use tag to recognized which cell’s button been clicked
另外因為dequeueReusableCell的特性,在cellForItemAt要設定button image,不然上下滑動cell後image會跑掉(例如:播放中的stop image被改成play image)
currentPlayingItemButton是正在播放音樂的button,音樂播完後要改nil
override func collectionView(_ collectionView: UICollectionView, cellForItemAt......//設定button tag, addTarget
cell.playButton.tag = indexPath.row
cell.playButton.addTarget(self, action: #selector(playButtonGroupAction(sender:)), for: .touchUpInside)...//設定button image
if cell.playButton.tag == currentPlayingItemButton?.tag{
cell.playButton.setImage(UIImage(systemName: "stop"), for: .normal)
}else{
cell.playButton.setImage(UIImage(systemName: "play"), for: .normal)
}
play music:
AVFoundation
let player = AVPlayer()這個要設在global area, 不能設在func裡面,func一結束就會被釋放了,會造成音樂連一秒都沒有播放
class iTunesController{...
let player = AVPlayer()...func playPreviewURL(_ url:URL){
let playerItem = AVPlayerItem(url: url)
player.replaceCurrentItem(with: playerItem)
player.play()
}
do something when play music done:
用NotificationCenter設定addObserver for AVPlayerItemDidPlayToEndTime
音樂播放完畢後,我想把button image從stop改成play,不知道為什麼都改不動(用DispatchQueue.main.async包起來也不行),目前先用reloadData(有成功,但畫面會閃一下),可能要研究一下DispatchQueue
NotificationCenter.default.addObserver(forName: Notification.Name.AVPlayerItemDidPlayToEndTime, object: nil, queue: .main) { (notification) in
//self.currentPlayingItemButton?.setImage(UIImage(systemName: "play"), for: .normal)
self.currentPlayingItemButton = nil
self.collectionView.reloadData()
}
Auto Layout:
好像有東西沒設定好(需要再研究),重畫cell時會跑出一大堆LayoutConstraints debug message,可以暫時用這行關掉
//Hide Autolayout Warning
UserDefaults.standard.set(false,forKey:"_UIConstraintBasedLayoutLogUnsatisfiable")
Reference: