[iOS] AVAudioPlayerはメソッド内の一時変数じゃなくてインスタンスプロパティにする

2015/10/1

こんにちは。きんくまです。

タイトルのままなんですが、どうにもいかずハマったのでメモ。
swift版の計算機アプリを作っていて、ボタン押したらSE鳴らしたいよなーと思いAVAudioPlayer使ってみようとしました。

でもやれどもやれども、鳴りません。

鳴らないコード

import UIKit
import AVFoundation

class ViewController: UIViewController {
    @IBAction func buttonTapped(){
        var player:AVAudioPlayer?
        
        let filePath:String? = NSBundle.mainBundle().pathForResource("mysound", ofType: "wav")
        print("path = \(filePath)")
        let fileURL:NSURL? = NSURL.fileURLWithPath(filePath!)
        print("URL = \(fileURL)")
        
        do {
            try player = AVAudioPlayer(contentsOfURL: fileURL!)
        }catch{
            print("error")
        }
        print("player \(player)")
        player?.prepareToPlay()
        player?.play()
    }
}

printも filePath, fileURL, player全部作られたよー出力されます。なのに鳴らない、、。

で、解決策はStackOverflowにありました。

>> iOS Swift 2.0 – AvAudioPlayer is not playing any sound

import UIKit
import AVFoundation

class ViewController: UIViewController {
    var player:AVAudioPlayer?

    @IBAction func buttonTapped(){
        //ここに書いちゃだめ!
        //var player:AVAudioPlayer?
        
        let filePath:String? = NSBundle.mainBundle().pathForResource("mysound", ofType: "wav")
        print("path = \(filePath)")
        let fileURL:NSURL? = NSURL.fileURLWithPath(filePath!)
        print("URL = \(fileURL)")
        
        do {
            try player = AVAudioPlayer(contentsOfURL: fileURL!)
        }catch{
            print("error")
        }
        print("player \(player)")
        player?.prepareToPlay()
        player?.play()
    }
}

メソッド内で一時変数を宣言してもだめで、インスタンスプロパティにしないといけないのでした。
たぶんメソッド内の一時的な変数だと、音を鳴らしている最中にメモリからクリアされちゃうってことだと思われ、、。

ずっと前にもFlashで音鳴らすときに同じようなところでハマった気がする、、。

計算機アプリの方は、「とにかく最小限の機能でまずリリース!」ということを目標にしてまして、もうすぐできそうです。

LINEで送る
Pocket

自作iPhoneアプリ 好評発売中!
フォルメモ - シンプルなフォルダつきメモ帳
ジッピー電卓 - 消費税や割引もサクサク計算!

LINEスタンプ作りました!
毎日使える。とぼけたウサギ。LINEスタンプ販売中! 毎日使える。とぼけたウサギ

ページトップへ戻る