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

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

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

### 環境
Xcode 11.2
Swift 4.2
IOS 13.2
## 問題点
Info.plistで Privacy- Media Library Usage Descriptionを設定すればアクセス許可画面は出ますけど
その画面が一回しか出ないのでもしユーザーが許可なしを選択したら、アプリ内でボタン押しても反応がなくなってしまった。
<img width="768" alt="IMG_0008.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538468/751d845e-7f0b-46d5-d062-4518bd3e0b01.png">

## 解決策
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)
        }
    }
```
<img width="768" alt="IMG_0009.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538468/93720f19-a44a-5baa-1903-769ae96b5ff4.png">
### 選択画面で設定しますを押す時
```
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)
    }
```


<img width="768" alt="IMG_0010.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538468/e2d63543-904b-5517-603c-7de6332e6424.png">

### 全体コード

```
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)
    }
}

```