ちょっとしたiPadアプリを作った話

シンプルなBGMアプリほしい

— なおてぃーさん (@naoty_k) 11月 23, 2012

好きな曲のyoutubeのリンクをHerokuとかにアップしておいて、iPadでそれらをリストを取得してエンドレスで聞けるようにしたい

— なおてぃーさん (@naoty_k) 11月 23, 2012

↑というのを思いつき、2日間でプロトタイプを作ってみた。

http://distilleryimage9.s3.amazonaws.com/25d59dd6361c11e2b3e122000a1f9a4f_7.jpg

ジョジョOPでテンション上げながら。

http://distilleryimage10.s3.amazonaws.com/5837a310363e11e28ed022000a1fbc58_7.jpg

サーバー側をRails on Herokuで作って、そっからデータを取得までできた。

アプリとサーバーのコードはこちらで公開してます。

YouTube再生プレイヤー

YouTubeの再生プレイヤーはUIWebViewにiframeを埋め込んで実装した。MPMoviePlayerControllerというのでもできそうな感じがするけど、時間かかりそうなので、とりあえずUIWebViewを選択。

iframeはYoutubeの動画の下のところから取ってこれるものを使う。↓こんなの。

<iframe width="560" height="315" src="http://www.youtube.com/embed/UqFvrjhbO8c?rel=0" frameborder="0" allowfullscreen></iframe>

あとは、UITableViewで選択した動画のIDをUIWebViewに渡してリロードすることで、動画を切り替える。

サーバーとの通信

サーバーとの通信はAFNetworkingという便利ライブラリを使って実装した。外部ライブラリのインストールにはCocoaPodsを初めて使ってみた。RailsのBundlerに慣れると、iOSの外部ライブラリの管理がしんどく感じるけど、これでだいぶ楽になれる。

platform :ios, '6.0'
pod 'AFNetworking'

↑のようなファイルをPodfileという名前でプロジェクトのルートディレクトリに置いて(Gemfileっぽい)

$ pod install

して、できた*.xcworkspaceを方を使うと簡単に外部ライブラリを使えるようになる。

自動再生

ここまではそんなに時間がかからなかったけど、ここから

  • HTMLがロードされたら自動で動画を再生する
  • 動画が終了したら自動で次の曲に移る

の2つを実装するのに、相当手こずってる(現在進行形)。

YouTubeのiFrameプレイヤーをJavaScriptで制御するYouTube Player APIというものがあるので、これを使ってプレイヤーのロード時、動画再生終了時のイベントを受け取る。詳しい実装方法はリンク先のとおりだけど、ポイントは以下のところ。

function onPlayerStateChange(event) {
    if (event.data == YT.PlayerState.ENDED) {
        document.location = "api://didEndedMovie";
    }
}

これで再生終了時のイベントを受け取って、api://didEndedMovieをロードすることができる。

UIWebViewでのロードはUIWebViewDelegateでキャッチすることができるので、これをうまく使うことでJSからアプリ側への通知を実装する。

- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
    NSString *requestString = [[request URL] absoluteString];

    if ([requestString isEqualToString:@"api:didEndedMovie"]) {
        // 再生終了時の処理をここに実装する

        return NO;
    }

    return YES;
}

このデリゲートメソッドの返り値をYESにするとUIWebViewはページ遷移するが、NOにするとページ遷移しない。リクエスト先を見てapi://didEndedMovieであれば、再生終了時の処理を実行しNOを返す。

これで再生終了時に次の動画に自動的に移すことが可能

…かと思いきや、なぜかうまくいかないorz

デバッグをしてみると、どうやらJSのonPlayerStateChangeが呼ばれていないっぽい。ブラウザではうまくいっていたので、UIWebViewのみで起きる現象のようだけど、原因がよくわからない…。というところで、今週の土日が終わりました。


以下のページを参考にさせていただきました。ありがとうございました。