0
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

楽天ブックスCD検索APIから画像、タイトル、アーティスト名、レーベル、説明文、曲名を取得

Posted at

今回の内容

283F9428-C50F-4425-B63A-BDEA80A78844_1_201_a.jpeg

コード

Model

MusicDetailModel
struct MusicDetailModel{
    
    let mediumImageUrl:String?
    let title:String?
    let artistName:String?
    let label:String?
    let itemCaption:String?
    let playList:String?
}
import Alamofire
import SwiftyJSON

class AlamofireProcess{
    
    private var privateMediumImageUrl:String?
    private var privateTitle:String?
    private var privateArtistName:String?
    private var privateLabel:String?
    private var privateItemCaption:String?
    private var privatePlayList:String?
    
    private var getMusicDataArray = [MusicDetailModel]()
}

extension AlamofireProcess{
    
    public func getMusicData(searchKeyword:String?,completion: @escaping ([MusicDetailModel]?,Error?) -> Void){
        
        guard let keyword = searchKeyword else { return }
        
        let apikKey = "https://app.rakuten.co.jp/services/api/BooksCD/Search/20170404?format=json&artistName=\(keyword.urlEncoded)&applicationId=アプリID"
        
        AF.request(apikKey, method: .get, parameters: nil, encoding: JSONEncoding.default).responseJSON {[self] response in
            
            switch response.result{
                
            case .success:
                
                let detailData = JSON(response.data as Any)
                
                for dataCount in 0..<detailData["Items"].count{
                    
                    getDataNilCheck(checkMediumImageUrl: detailData["Items"][dataCount]["Item"]["mediumImageUrl"].string,
                                    checkTitle: detailData["Items"][dataCount]["Item"]["title"].string,
                                    checkArtistName: detailData["Items"][dataCount]["Item"]["artistName"].string,
                                    checkLabel: detailData["Items"][dataCount]["Item"]["label"].string,
                                    checkItemCaption: detailData["Items"][dataCount]["Item"]["itemCaption"].string,
                                    checkPlayList: detailData["Items"][dataCount]["Item"]["playList"].string)
                    
                    getMusicDataArray.append(MusicDetailModel(mediumImageUrl: privateMediumImageUrl,
                                                              title: privateTitle,
                                                              artistName: privateArtistName,
                                                              label: privateLabel,
                                                              itemCaption: privateItemCaption,
                                                              playList: privatePlayList))
                }
                
                completion(getMusicDataArray, nil)
                
            case .failure(let error):
            
                completion(nil, error)
            }
        }
    }
}

extension AlamofireProcess{
    
    private func getDataNilCheck(checkMediumImageUrl:String?,checkTitle:String?,checkArtistName:String?,checkLabel:String?,checkItemCaption:String?,checkPlayList:String?){
        
        if checkMediumImageUrl != nil{
            
            privateMediumImageUrl = checkMediumImageUrl
        }else{
            
            privateMediumImageUrl = "noSign"
        }
        
        
        if checkTitle != nil{
            
            privateTitle = checkTitle
        }else{
            
            privateTitle = "読み込みエラー"
        }
        
        if checkArtistName != nil{
            
            privateArtistName = checkArtistName
        }else{
            
            privateArtistName = "読み込みエラー"
        }
        
        if checkLabel != nil{
            
            privateLabel = checkLabel
        }else{
            
            privateLabel = "読み込みエラー"
        }
        
        if checkItemCaption != nil{
            
            privateItemCaption = checkItemCaption
        }else{
            
            privateItemCaption = "読み込みエラー"
        }
        
        if checkPlayList != nil{
            
            privatePlayList = checkPlayList
        }else{
            
            privatePlayList = "読み込みエラー"
        }  
    }

}

extension String{
    
    var urlEncoded:String{
        
        let charset = CharacterSet.alphanumerics.union(.init(charactersIn: "/?-._~"))
        let remove = removingPercentEncoding ?? self
        
        return remove.addingPercentEncoding(withAllowedCharacters: charset) ?? remove
    }
}

View

C813F240-8B4E-4811-B5E6-93B9CF643C72_4_5005_c.jpeg
CollectionCustomCell
import UIKit

class CollectionCustomCell: UICollectionViewCell {

    @IBOutlet weak var mediumImageView: UIImageView!
    @IBOutlet weak var detailTextView: UITextView! 
    
    override func awakeFromNib() {
        super.awakeFromNib()
       
    }

    required init?(coder: NSCoder) {
        super.init(coder: coder)
      
    }
    
    override func prepareForReuse() {
        super.prepareForReuse()
        
        mediumImageView.image = UIImage(named: "")
        detailTextView.text = ""
    }
}
MusicDetailViewController
import UIKit
import SDWebImage

class MusicDetailViewController: UIViewController {

    @IBOutlet weak var mediumImageView: UIImageView!
    @IBOutlet weak var playListView: UITableView!
    
    public var playlistContentsArray = [String]()
    
    public var imageURL:URL?
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        mediumImageView.sd_setImage(with: imageURL, completed: nil)
        playListView.register(UINib(nibName: "TableViewCustomCell", bundle: nil), forCellReuseIdentifier: "MusicNameCell")
        playListView.dataSource = self
    }
   
}

extension MusicDetailViewController:UITableViewDataSource{
    
    func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
        
        return "PlayList"
    }
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        
        return playlistContentsArray.count
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        
        let cell = tableView.dequeueReusableCell(withIdentifier: "MusicNameCell", for: indexPath) as! TableViewCustomCell
        
        cell.musicNameLabel.text = playlistContentsArray[indexPath.row]
        
        return cell
    }
}
TableViewCustomCell
import UIKit

class TableViewCustomCell: UITableViewCell {
    
    @IBOutlet weak var musicNameLabel: UILabel!
    
    override func awakeFromNib() {
        super.awakeFromNib()
        
    }

    override func setSelected(_ selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)
      
    }
    
    required init?(coder: NSCoder) {
        super.init(coder: coder)
        
    }
    
    override func prepareForReuse() {
        super.prepareForReuse()
        
        musicNameLabel.text = ""
    }
    
}

Controller

  • 取得したplayListは曲名と曲名の間に###が存在するString型で取得されるので、tableViewに表示する為に、.components(separatedBy: "###")を使用しています。
ViewController
import UIKit
import SDWebImage

class ViewController: UIViewController {
    
    @IBOutlet weak var searchTextField: UITextField!
    @IBOutlet weak var searchButton: UIButton!
    @IBOutlet weak var resultCollectionView: UICollectionView!
    
    private let collectionViewLayout = UICollectionViewFlowLayout()
    
    private let alamofireProcess = AlamofireProcess()
    
    private var cellContentsArray = [MusicDetailModel]()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        resultCollectionView.register(UINib(nibName: "CollectionCustomCell", bundle: nil), forCellWithReuseIdentifier: "MusicDetailCell")
        resultCollectionView.delegate = self
        resultCollectionView.dataSource = self
    }
    
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        
        collectionViewLayout.sectionInset = UIEdgeInsets(top: 5, left: 5, bottom: 5, right: 5)
        resultCollectionView.collectionViewLayout = collectionViewLayout
    }

    @IBAction func artistNameSearch(_ sender: UIButton) {
        
        if searchTextField.text?.isEmpty != true{
            
            alamofireProcess.getMusicData(searchKeyword: searchTextField.text) { result, error in
                
                if error != nil{
                    
                    print(error.debugDescription)
                }
                
                DispatchQueue.main.asyncAfter(deadline: .now() + 5) {[self] in
                
                    cellContentsArray = result!
                    resultCollectionView.reloadData()
                }
            }
        }
    }
    
}

extension ViewController:UICollectionViewDelegate{
    
    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        
        let musicDetailVC = MusicDetailViewController()
        musicDetailVC.modalPresentationStyle = .automatic
        musicDetailVC.playlistContentsArray = []
        musicDetailVC.playlistContentsArray = (cellContentsArray[indexPath.row].playList?.components(separatedBy: "###"))!
        musicDetailVC.imageURL = URL(string: cellContentsArray[indexPath.row].mediumImageUrl!)
        self.present(musicDetailVC, animated: true, completion: nil)
    }
}

extension ViewController:UICollectionViewDataSource{
    
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        
        return cellContentsArray.count
    }
    
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "MusicDetailCell", for: indexPath) as! CollectionCustomCell
        
        cell.mediumImageView.sd_setImage(with: URL(string: cellContentsArray[indexPath.row].mediumImageUrl!))
        cell.detailTextView.text = """
                                   タイトル:
                                      \(cellContentsArray[indexPath.row].title ?? "読み込みエラー")
                                   
                                   アーティスト:
                                      \(cellContentsArray[indexPath.row].artistName ?? "読み込みエラー")
                                   
                                   レーベル:
                                      \(cellContentsArray[indexPath.row].label ?? "読み込みエラー")
                                   
                                   説明文:
                                      \(cellContentsArray[indexPath.row].itemCaption ?? "読み込みエラー")
                                   
                                   """
        
        return cell
    
    }
    
}

extension ViewController:UICollectionViewDelegateFlowLayout{
    
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        
        return CGSize(width: collectionView.frame.width / 2 - 10, height: collectionView.frame.height / 2 - 10)
    }
}

終わり

ご指摘、ご質問などありましたら、コメントまでお願い致します。

0
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?