頭と尻尾はくれてやる!

パソコンおやじのiPhoneアプリ・サイト作成・運営日記


iOSシミュレータだと音が鳴らない?

珍しい不具合が発生してさ、ちょっと調べてみたんだ。

iPhoneやiPad実機だと期待通り動くんだけど、iOSシミュレータだと落ちちゃうって不具合が発生したんだよ。
調べていくとさ、AVAudioPlayer使って音を鳴らすところあたりが怪しいってことがわかったんだ。
順を追って書いてくよ。

mp3ファイルの音を再生のために最初はこんなコードを書いていたんだ。
{
	//準備
	NSBundle *mainBundle = [NSBundle mainBundle];
	NSString *path = [mainBundle pathForResource:@"sound" ofType:@"mp3"];
	NSURL *url = [NSURL URLWithString:path];

	sound = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:nil];
	[sound prepareToPlay];
}

{
	//鳴らす
	[sound play];
}
書いてないけど、AVFoundationフレームワークを追加したりヘッダーでインポートしたり、soundはインスタンスなので宣言が必要だよ。
urlの記述あたりは人によってまとめてたりするからもしかしたら1行でsoundオブジェクトを書いてる人もいるかもしれないけど、ここは丁寧に書いてるね。

これを実機で動かすと期待通り音がするんだけど、シミュレータだと音がしないんだよね。
シミュレータだからそんなものかなあって今までスルーしてきたんだけどさ、さすがに落ちるようになって調べたわけなんだ。
調べるためにちょびっとだけ変更したのが次でちゃんとエラーを見られるようにもしたんだ。
{
	//準備
	NSBundle *mainBundle = [NSBundle mainBundle];
	NSString *path = [mainBundle pathForResource:@"sound" ofType:@"mp3"];
	NSURL *url = [NSURL URLWithString:path];
	NSError *error;
	sound = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:&error];
	[sound prepareToPlay];

	NSLog(@"[%p]",sound);
	if (sound) {
		NSLog(@"true");
	} else {
		NSLog(@"false");
    		NSLog(@"%@",error);
	}
}
if文は実機だとちゃんとtrueになるのに、シミュレータだとfalseになるしポインタも0x0になってる。で、errorを見てみると
Error Domain=NSOSStatusErrorDomain Code=-50 "The operation couldn’t be completed. (OSStatus error -50.)"
ってエラーメッセージが表示されるんだ。シミュレータだとAVAudioPlayerオブジェクトができていないみたい、、、?

このメッセージはなんだろうなって調べたらいつものサイトにあったよ、答えが。
URLWithString returns nil for resource path - iphone - Stack Overflow

またStack Overflowだよ。ホントいつもお世話になるね、ここは。
リンク先記事を参考に修正するとこんな感じ。
{
    //音の準備
    NSBundle *mainBundle = [NSBundle mainBundle];
    NSString *path = [mainBundle pathForResource:@"sound" ofType:@"mp3"];
    NSString *expandedPath = [path stringByExpandingTildeInPath];//追加
    //NSURL *url = [NSURL URLWithString:path];//やめ
    NSURL *url = [NSURL fileURLWithPath:expandedPath];//こっちにする
    NSError *error;

    sound = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:&error];
    [sound prepareToPlay];
}
変更点はパスをstringByExpandingTildeInPathメソッドで修正、NSURLオブジェクトの生成メソッドも変更してるよ。
このコードだと実機でもシミュレータでもちゃんと音が鳴るんだ。つまり今までは音のファイルのパス指定がまずかったみたいだね。

ただどういうわけかシミュレータの場合だけ「どうしたんや、節子?」ってくらい膨大なエラーメッセージ(?)がNSLogしたわけでもないのにコンソールに出てくるんだ。

エラーメッセージ

ちょっと精神的にグサっとくる画像だね。
まあすっきりしないんだけど、これ以上は深く考えないことにするよ。

ちなみに開発時にシミュレータで落ちてた原因はカラのAVAudioPlayerオブジェクトを配列に突っ込んでいたからで、上のテストコードだと落ちることはないと思うよ。

<< AVAudioPlayerのvolumeをゼロにしても音がなる?  TopPage  Dropboxのテキスト編集アプリ Nocs >>

コメント


管理者にだけ表示を許可する
 

トラックバック

トラックバックURL
http://ringsbell.blog117.fc2.com/tb.php/569-9a93682f




Copyright ©頭と尻尾はくれてやる!. Powered by FC2 Blog. Template by eriraha.

FC2Ad