ichigoryume programming blog

プログラミングに関する備忘録。主にHTML5, C#, Swiftなど。

MPMediaQueryを使ってiTunesLibraryから曲やアルバムなどを検索する

サマリ

  • import MediaPlayer して、MPMediaQueryクラスを使う
  • MPMediaQueryにはalbums()やartists()などのクラスメソッドがあり、これらをコールすると検索結果としてMPMediaQueryインスタンスが得られる
  • このインスタンスのitemsとcollectionsプロパティから検索結果を取得する
    • itemsはMPMediaItemの配列で、1インスタンス1曲
    • collectionsはMPMediaItemCollectionの配列。このクラスはMPMediaItemをグルーピングするもので、MPMediaItemのは配列itemsプロパティを持っている。albums()をコールした場合はアルバムで、artists()をコールした場合はアーティストでグルーピングされている
    • MPMediaItemCollectionのrepresentativeItemプロパティにはそのグループの代表的なMPMediaItemインスタンスがセットされる
  • MPMediaQueryのaddFilterPredicate()メソッドを使うとさらに絞り込みができる
  • MPMediaQueryクラスを使うには、iTunesライブラリにアクセスするための設定とコードが必要!

準備

iTunesライブラリにアクセスするために、Info.plistに設定項目を追加する

  • key : Privacy - Media Library Usage Description
  • value : To Play Music (適当でいい)

ユーザーに対してiTunesライブラリへのアクセス許可を求めるダイアログをアプリ起動時に表示する

requestAuthorization()メソッドをコールした直後はまだダイアログがでてないので、続けてMPMediaQueryに関するコードを書かないこと。viewDidLoad()を一旦抜ける必要がある。

    var authroized:Bool = false

    override func viewDidLoad() {
        super.viewDidLoad()

        MPMediaLibrary.requestAuthorization { status in
            if status == .authorized {
                    self.authroized = true
            }
        }
    }

全曲リストアップ

    @IBAction func touchUpInside(_ sender: Any) {

        if(authroized == false) {
            return
        }
        
        let query = MPMediaQuery.songs()
        guard let songs = query.items else {
            return
        }
        
        for song in songs {
            print(song.title ?? "unknown")
        }
    }

アルバムごとにアルバム名と曲一覧を表示

    @IBAction func touchUpInside(_ sender: Any) {

        if(authroized == false) {
            return
        }
        
        let query = MPMediaQuery.albums()

        for album in query.collections ?? [] { // コレクションプロパティなのがポイント
            print(album.representativeItem?.albumTitle ?? "unknown")
            
            for song in album.items {
                print("  " + (song.title ?? "unknown"))
            }
        }
    }

曲名に指定した文字列を含む曲を検索

ひらがなの「の」を含む曲を検索する場合

    @IBAction func touchUpInside(_ sender: Any) {

        if(authroized == false) {
            return
        }
        
        let query = MPMediaQuery.songs()

        let predicate = MPMediaPropertyPredicate(value: "の", forProperty: MPMediaItemPropertyTitle, comparisonType: MPMediaPredicateComparison.contains)
        query.addFilterPredicate(predicate)
        
        for song in query.items ?? [] {
            print(song.title ?? "unknown")
        }
    }

曲やアルバムのIDで検索

曲やアルバムは恒久的なIDを持っていて、このIDで検索/絞り込みができる
アルバムのIDで絞り込みをする例

    func FindAlbumByID(albumID:MPMediaEntityPersistentID?) -> MPMediaItemCollection? {
        
        let predicate = MPMediaPropertyPredicate(value:albumID, forProperty:MPMediaItemPropertyAlbumPersistentID)
        let query = MPMediaQuery.albums()
        query.addFilterPredicate(predicate)
        
        return query.collections?[0]
    }

プレイリストの一覧を表示する

検索結果のcollectionsのvalue()メソッドを使ってプレイリスト名を取得するのがポイント

    @IBAction func touchUpInside(_ sender: Any) {

        if(authroized == false) {
            return
        }
        
        let query = MPMediaQuery.playlists()

        for playlist in query.collections ?? [] {
            
            let playlistName = playlist.value(forProperty: MPMediaPlaylistPropertyName) ?? "no name"
            print(playlistName)
        }
    }

MPMediaItemのartworkを表示する

例えば、UIViewを継承するクラスで自身にアートワークをセットするメソッドはこんな感じ

    func updateArtwork(artwork:MPMediaItemArtwork?) {

        guard let _artwork = artwork else {
            self.image = nil
            return
        }
        
        self.image = _artwork.image(at: self.frame.size)
    }