げぇむぷろぐらみんぐ

日々の生活で得た知識、経験を書きます

ReactNativeでミュージックストリーミングサーバーkoelのネイティブアプリ作ってみた

ネタがなかったので、ゲーム関係ないですが、NITMic Advent Calendar 2017 16日目の記事です。
一応うちの部活はゲーム開発を行うだけの部活ではない!(らしい)ので、セーフです。

今までゲームばっかり作ってきていたのですが、最近はあるきっかけから割りとゲーム開発以外もやってみたいなあという思いが一段と強くなり、その流れからReactNativeでネイティブアプリを作ってみました。

今回は、開発環境と、使ったコンポーネントについてだけ書きます。

アプリ開発は初なので温かい目で見て下さい。
完成形はこんな感じです。 個人用なのでUIとか知りません。
iphoneのミュージックアプリを参考に作りました。
とりあえず、目標としていたバックグラウンド再生、シャッフル再生、プレイリストごとの再生はできたので満足です!

f:id:siguma_sig:20171215213921g:plain

ミュージックストリーミングサーバー koel

以前、こちらでも紹介したのですが、OSSな個人用ミュージックストリーミングサーバーを簡単に立てられるのがkoelです。

フロントがVue.js、サーバーサイドがLaravelで書かれており、公式サイトにも書いてありますが割りとモダンな感じです。
OSSなVue.jsのアプリではかなり有名な方らしく、Vue.jsの実装の参考にもされるらしいです。

僕は作業中はずっと音楽を流しているのですが、色んな端末に音源を入れるのが面倒なので使っています。
ですが、公式でiOS/Androidのネイティブアプリが存在しなかったため、今回作ってみようと思いました。

技術選定

サーバーサイドに関しては、API一覧などは存在しないので、頑張ってLaravelの実装を読んでWebアプリで使われているAPIを叩くだけです。

クライアントサイドに関して、初めにSwiftをこの機会に学んでみようかとも思いましたが、直近でReactを使ってSPAな自分用ツールを作っていたので、ReactNativeで行こうと思いました。
また、今回は自分用なのでiOSのみで良いのですが、クロスプラットフォームなところにも惹かれました。

開発環境

初めは、create-react-native-appを用いて開発をはじめました。
Expoというものを利用していて、QRコードで実機での動作確認がすぐできて便利でした。
がしかし、こちらはネイティブプラグインが基本的には利用できず、ネイティブAPIはExpo側で用意されたものだけしか使えません。
音楽再生のネイティブAPIも提供されていたのですが、こちらはバックグラウンド再生ができなかったので泣く泣く諦めました。

結局、react-native-cliからプロジェクトを作り直して開発を行いました。

エディタは、WebStormを使いました。学生のうちに使ってみたかっただけで、基本的にはVSCodeで良さそうでした。
今回は、TypeScriptやFlow、ESlintなどは利用せず開発を行いました。理由は導入が大変そうだったからです。
ただ、このアプリの開発が終わったあとにESlintを入れてみたら大変便利で、非常に後悔しているので、ESlintは少なくとも入れたほうが良さそうです。
Reactのお作法の勉強にもなります。

便利だったコンポーネント紹介

react-native-video
これがなければ作れなかった。
videoとついてるが、audioのみも再生できる。
他にも、サウンド再生系のコンポーネントはいくつかあるが、他はほぼメンテされていなかったりしたのでこれにした。
ボリュームをいじったり、再生時間をいじったりもできる。

redux
言わずもがな
Fluxの概念を拡張して、stateを管理するためのフレームワーク
僕のような素人でも書き方が大体決まっているので、コードがぐっちゃぐちゃにはなりづらかった。

redux-actions
reduxのactionCreatorを決まった形式で簡単に作れる。
実装方法を縛ることで複数人で書くときも書き方が統一されて良さそう。

export const increment = createAction(COUNTER_INCREMENT);

こんな感じで、incrementのactionが作れる。 引数はpayloadに乗っかる感じ。

redux-saga
非同期処理で大変お世話になった。
初めは、redux-thunkを使っていたけど、APIを叩いたりの非同期処理がactionCreator側に有るのがどうにも気持ち悪かったのを同期に相談したら教えてもらった。
redux-sagaで非同期処理と戦うがとっても参考になる。

下のようにAPIを叩いてPromiseを返すメソッドを用意して、

saga側で呼び出して、返ってきた値を用いてactionをdispatchということができる。

導入の際に覚えることがいくつかあるけど、それに見合ったメリットはあると思った。

react-native-router-flux
Webフロントのreact-routerライクに画面遷移が書ける。
初めは、react-navigationを使ってみたが、よくわからなかったので、使いやすそうなこちらにした。
ただ、中ではreact-navigationが動いてるらしい。
react-native-navigationというのもあるらしいが、使わなかった。遷移のアニメーションが豊富らしい?

他には、lodashとかreact-native-vector-iconsとかも使った。

まとめ

初コミットから見ると、約2週間くらいで完成しました。
ネイティブアプリ開発の経験もなく、Reactのアプリ開発経験もほぼほぼないと言っていいくらいだったけどこんな感じなので、割りと取っ付きやすいのかなあと思いました。
とはいえ、パフォーマンスを気にしたりし始めるとまだまだ学ぶことは多そうです。
アプリをリリースするときは、そういうところもきちんとしないといけないと思うし、UI/UXの勉強も必要だなあと思いました。

とはいえ、普段のゲーム開発とは全く違うことをするのも楽しかったです。
こんな感じで就職するまでは、フラフラ色んな技術に浮気しつつ、ゲームも遊びつつ、ゲーム開発の知識も増やしていきたいです。

研究頑張ります…。