【初心者向け】Swift3で爆速コーディングその５(サウンドとデリゲート)

Playgroundによるコーディングです。
初めての方は下記をご参考ください。

第１回：[【初心者向け】Swift3で爆速コーディングその１(画面作成とSnippetsの使い方)](http://qiita.com/teradonburi/items/d0ffb6367e34966d761b)
第２回：[【初心者向け】Swift3で爆速コーディングその２(UIViewと文字表示)](http://qiita.com/teradonburi/items/fe79959d692c7efc99d1)
第３回：[【初心者向け】Swift3で爆速コーディングその３(ボタンクリックとイベント)](http://qiita.com/teradonburi/items/381aabdf547977953d48#_reference-4e99e4f5de9c0f6c2d05)
第４回：[【初心者向け】Swift3で爆速コーディングその４(画像とアニメーション)](http://qiita.com/teradonburi/items/389fadf28215944f1054)

# ソースコード
今回の全ソースコードです。

```
import UIKit
import AVFoundation

class ViewController: UIViewController,AVAudioPlayerDelegate {
    
    var audioPlayer : AVAudioPlayer!
    var button : UIButton!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        
        // 再生する音源のURLを生成
        let soundFilePath : String = Bundle.main.path(forResource: "sound", ofType: "mp3")!
        let fileURL : URL = URL(fileURLWithPath: soundFilePath)
        
        
        do{
            // AVAudioPlayerのインスタンス化
            audioPlayer = try AVAudioPlayer(contentsOf: fileURL)
            
            // AVAudioPlayerのデリゲートをセット
            audioPlayer.delegate = self
            
            
        }
        catch{
        }
        
        //ボタンの生成
        button = UIButton()
        button.frame = CGRect(x:0,y:0,width:100, height:30)
        button.setTitle("▶︎", for: UIControlState.normal)
        button.setTitleColor(UIColor.black, for: .normal)
        button.backgroundColor = UIColor.green
        button.layer.masksToBounds = true
        button.layer.cornerRadius = 10.0
        self.view.addSubview(button)
        button.addTarget(self, action: #selector(self.onClick(_:)), for: UIControlEvents.touchUpInside)
        
    }

    // ボタンがタップされた時に呼ばれるメソッド
    func onClick(_ sender: UIButton) {
    
        // playingプロパティがtrueであれば音源再生中
        if audioPlayer.isPlaying == true {
        
            // audioPlayerを一時停止
            audioPlayer.pause()
            sender.setTitle("▶︎", for: .normal)
        } else {
        
            // audioPlayerの再生
            audioPlayer.play()
            sender.setTitle("■", for: .normal)
        }
    }

    // 音楽再生が成功した時に呼ばれるメソッド
    func audioPlayerDidFinishPlaying(_ player: AVAudioPlayer, successfully flag: Bool) {
        print("Music Finish")
    
        // 再度myButtonを"▶︎"に設定
        button.setTitle("▶︎", for: .normal)
    }

    // デコード中にエラーが起きた時に呼ばれるメソッド
    func audioPlayerDecodeErrorDidOccur(_ player: AVAudioPlayer, error: Error?) {
        print("Error")
    }

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        
        
    }

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

let viewController = ViewController()
viewController.view.backgroundColor = UIColor.white


import PlaygroundSupport


PlaygroundPage.current.liveView = viewController
PlaygroundPage.current.needsIndefiniteExecution = true
```

# プレビュー
再生ボタンを押したら、サウンドを再生します。

<img width="998" alt="スクリーンショット 2016-09-27 22.00.50.png" src="https://qiita-image-store.s3.amazonaws.com/0/55077/aa759cbc-a829-2bcf-057c-bb7501a2cb89.png">

# デリゲート
delegateは処理を移譲する機能です。
概念的にはJavaとかのインタフェースに近いです。
delegateを継承したクラスはdelegateメソッドを実装する必要があります。（optionalのメソッドは実装任意です）
今回はAVAudioPlayerクラスのイベント処理をするためAVAudioPlayerDelegateを使います。

```
class ViewController: UIViewController,AVAudioPlayerDelegate {
```

ViewDidLoadでデリゲートをセットします。

```
// AVAudioPlayerのデリゲートをセット
audioPlayer.delegate = self
```

今回はaudioPlayerDidFinishPlayingメソッドとaudioPlayerDecodeErrorDidOccurメソッドを実装します。

```
// 音楽再生が成功した時に呼ばれるメソッド
func audioPlayerDidFinishPlaying(_ player: AVAudioPlayer, successfully flag: Bool) 
// デコード中にエラーが起きた時に呼ばれるメソッド
func audioPlayerDecodeErrorDidOccur(_ player: AVAudioPlayer, error: Error?) 
```

# サウンド
サウンド周りのライブラリを利用するにはAVFoundationフレームワークをインポートします。

```
import AVFoundation
```

サウンドファイル（sound.mp3）を追加します。
適当なサウンドファイルを用意してください
追加の仕方は画像と同じなので第４回を参考にしてください

<img width="394" alt="スクリーンショット 2016-09-27 22.12.05.png" src="https://qiita-image-store.s3.amazonaws.com/0/55077/c92c656b-730b-16a9-e978-4fe7c045dc3d.png">

サウンドファイルをロードします。

```
// 再生する音源のURLを生成
let soundFilePath : String = Bundle.main.path(forResource: "sound", ofType: "mp3")!
let fileURL : URL = URL(fileURLWithPath: soundFilePath)
        
        
do{
    // AVAudioPlayerのインスタンス化
    audioPlayer = try AVAudioPlayer(contentsOf: fileURL)            
    // AVAudioPlayerのデリゲートをセット
    audioPlayer.delegate = self            
            
}
catch{

}
```

ボタンが押されたらonClickメソッドが呼ばれ、
サウンドを再生します。再生中なら一時停止になります。
ボタンとコントロールのイベント処理に関しては第３回を参考にしてください

```
// playingプロパティがtrueであれば音源再生中
if audioPlayer.isPlaying == true {
        
   // audioPlayerを一時停止
   audioPlayer.pause()
   sender.setTitle("▶︎", for: .normal)

} else {
        
   // audioPlayerの再生
   audioPlayer.play()
   sender.setTitle("■", for: .normal)
}

```

再生が終わるとデリゲートのメソッドがコールバックされます。
デリゲートのメソッドはこのようにコールバックメソッドがほとんどです。

```
// 音楽再生が成功した時に呼ばれるメソッド
func audioPlayerDidFinishPlaying(_ player: AVAudioPlayer, successfully flag: Bool) 
```