MPMediaLibraryへアクセス許可を促す(不許可されても)


オークファンAdvent Calendar 12日です。

弊社に19新卒で入社して半年強が経ちました。
業務でPHPを使っており、プライベートでモバイルアプリ開発しています。
自作のアプリは審査の時でリジェクトされた問題点を書きます。

環境

Xcode 11.2
Swift 4.2
IOS 13.2

問題点

Info.plistで Privacy- Media Library Usage Descriptionを設定すればアクセス許可画面は出ますけど
その画面が一回しか出ないのでもしユーザーが許可なしを選択したら、アプリ内でボタン押しても反応がなくなってしまった。

解決策

UIAlertControllerで選択画面を作り、設定画面まで飛ばせる。

authorizationStatus 説明
.notDetermined 未選択
.denied 不許可
.authorized 許可

音楽選択ボタンを押す時

@IBAction func pickMusic(_ sender: Any) {

        let status = MPMediaLibrary.authorizationStatus()
     //MPMediaLibraryにアクセスできない、選択画面を表示
        if status == .denied {
            self.displayPermissionViewController()
        } else {
            let picker = MPMediaPickerController(mediaTypes: MPMediaType.music)
            picker.delegate = self
            self.present(picker, animated: true, completion: nil)
        }
    }

選択画面で設定しますを押す時

func displayPermissionViewController() {
        let alert = UIAlertController(title: "メディアライブラリのアクセス許可を設定しますか?", message: "音楽選択するため", preferredStyle:  UIAlertController.Style.alert)

        alert.popoverPresentationController?.sourceView = self.view

        let cancelAction = UIAlertAction(title: "キャンセル", style: .default, handler: nil)
        alert.addAction(cancelAction)

        let okAction = UIAlertAction(title: "設定します", style: .default) { _ in
       // セッティング画面に行く
            if let url = URL(string: UIApplication.openSettingsURLString) {
                UIApplication.shared.open(url, options: [:], completionHandler: nil)
            }
        }
        alert.addAction(okAction)
        present(alert, animated: true, completion: nil)
    }

全体コード

import UIKit
import MediaPlayer
class ViewController: UIViewController, MPMediaPickerControllerDelegate{

    override func viewDidLoad() {
        super.viewDidLoad()
    }

    @IBAction func pickMusic(_ sender: Any) {

        let status = MPMediaLibrary.authorizationStatus()
        //MPMediaLibraryにアクセスできない、選択画面を表示
        if status == .denied {
            self.displayPermissionViewController()
        } else {
            let picker = MPMediaPickerController(mediaTypes: MPMediaType.music)
            picker.delegate = self
            self.present(picker, animated: true, completion: nil)
        }
    }

    func displayPermissionViewController() {
        let alert = UIAlertController(title: "メディアライブラリのアクセス許可を設定しますか?", message: "音楽選択するため", preferredStyle:  UIAlertController.Style.alert)

        alert.popoverPresentationController?.sourceView = self.view

        let cancelAction = UIAlertAction(title: "キャンセル", style: .default, handler: nil)
        alert.addAction(cancelAction)

        let okAction = UIAlertAction(title: "設定します", style: .default) { _ in
            // セッティング画面に行く
            if let url = URL(string: UIApplication.openSettingsURLString) {
                UIApplication.shared.open(url, options: [:], completionHandler: nil)
            }
        }
        alert.addAction(okAction)
        present(alert, animated: true, completion: nil)
    }

    func mediaPickerDidCancel(_ mediaPicker: MPMediaPickerController) {
        dismiss(animated: true, completion: nil)
    }

    func mediaPicker(_ mediaPicker: MPMediaPickerController, didPickMediaItems mediaItemCollection: MPMediaItemCollection) {
        let musicPlayer = MPMusicPlayerController.applicationMusicPlayer
        musicPlayer.setQueue(with: mediaItemCollection)
        musicPlayer.play()
        dismiss(animated: true, completion: nil)
    }
}