ミクシィでは2020年6月末に、新感覚スポーツベッティングサービス『TIPSTAR(ティップスター)』をリリースしました。『TIPSTAR』は365日配信されるライブ動画と、現在は競輪を友達と一緒に楽しむことができるサービスです。
『TIPSTAR』のスマホアプリは、ミクシィが有するUI/UX技術を駆使して、エンターテインメント性の高いサービスを目指しました。アニメーションやレイアウトの表現といった表面的な部分から、ユーザーの操作性を邪魔しない裏側のシステムに至るまで、さまざまな工夫が凝らされています。今回は、iOSアプリエンジニアである堀江(写真 左)と寺田(写真 右)、そしてAndroidアプリエンジニアである山田(写真 右奥)に、ネイティブアプリ開発のこだわりについて語ってもらいました。
『TIPSTAR』の過去の記事について
♯1 低コストで高品質って両立できるの? 『TIPSTAR』の“映像伝送システム”の仕組みとは
♯2 AIが勝手に映像を編集? 映像自動編集の仕組みに迫る
♯3 「現場の負担を軽減しなければ……」 実現したのは、ブラウザでの映像編集
♯4フロントはReact、バックエンドはGo、DBはCloud Spanner。 さて、その理由は?
━━まずはこれまでの開発プロジェクトの流れを教えてください。
堀江 2019年に『TIPSTAR』の前身となるサービスの開発が始まり、8月のコンセプト&UIの見直しを経て、iOS先行で開発がスタートしました。iOSは10月頃から、Androidは11月頃から着手しました。
山田 実は8月頃までは、動画視聴サービスというコンセプトは変わらないものの、シンプルに車券購入ができることを重きに置いたアプリを開発していました。見やすさと利便性を重視した開発ですね。
堀江 確か、2タップで車券を購入できるような設計でしたよね。デザインも黒と白をベースにしたシンプルなものでした。その後、何度か方針転換があり、今の形になったんです。車券購入アプリではなく、新しいエンターテインメントを体現するプロダクトの姿を追求した結果ですが。ダイナミックな変更が多かったので、変化に強いコードを書こうという意識がチーム内で高まったのは良かったと思います。
━━iOSとAndroidの違いはどんなところにありますか?
山田 UIパーツは一部が異なりますが、画面遷移や機能面ではほぼ同じです。
━━なるほど。見た目や操作性の部分は同じように作られているんですね。まずはiOSアプリの技術構成について伺いたいのですが。
堀江 言語はSwiftで、アーキテクチャーはMVVMを採用しています。Swiftを選択したのは、そもそもiOSの開発言語には、メジャーなObjective-CとSwiftとそんなに選択肢がない中で、Swiftのほうが新しくできた言語ということもあり書きやすかったから。なので、必然的にSwiftを選択したというのが正直なところです。MVVMについては、割と一般的なアーキテクチャーではあると思います。『TIPSTAR』は映像や動画を見るだけでなく、アニメーションを多用したアプリになるので、コードでアニメーションを表現するためにStoryboardではなくMVVMを採用しています。
━━MVVMを使うメリットはどういったところで現れてくるんでしょうか。
寺田 Storyboardでの開発はほとんどコードを書く必要がなく、画面にパーツを置いていくだけなので比較的進めやすい利点もあるのですが、端末の画面サイズに対してアジャストさせていくのが難しいという問題があるので、コードでレイアウトを作る方法を選択したんですよね。
堀江 そうですね。他にも無限スクロールでMVVMが活きています。『TIPSTAR』は動画サービスなので、メモリの消費を抑えながら別映像の無限スクロールを可能にするにはどうすべきか、を考えるのが至難の業でした。具体的には、決められた領域をスクロールさせてエンドが近づいてきたら、シュッと自然に戻らないといけない。動画も再生しているのでメモリの使用量は結構重たい。だからこそ、最低限の数で回せるようにしています。
━━もしメモリの使用量を気にしないのであれば、どのような対処になりますか?
堀江 スクロール位置のエンドが近づいたらスタートに戻すというのを何も気にせずやるだけですね。例えば、一つの画面をコピーして、一枚目から二枚目に切り替わったときに、無限スクロールに見せるように同じように表示していく。完全に移動が完了したら位置を入れ替えていくことによって、スクロールしているように見せかける。ただその場合、同じものをコピーしているので、2倍領域を使ってしまいます。さらに動画配信をしているので、軽はずみにコピーしてしまうと再生位置がズレてしまう。こっちの映像は30秒を経過していて、一方の動画は10秒しか経過していないというように、というように。iOSの場合はロードを挟みたくなかったので、真ん中を契機にして情報を切り替えて再生を切り替えています。
━━すごく細かいけれど大変な調整になるんですね…!Androidの技術構成についても聞かせていただけますか?
山田 言語はKotlinで、アーキテクチャーはiOSと同じMVVMです。アニメーションを表現するため、AndroidXのコンポーネントにあるMotionLayoutに依存しています。世に出ているアプリの中で採用されていないようなものなので、これは結構特徴的なところかもしれませんね。データのやりとりはLiveDataを使用。画面起動時ではなく、データが必要になったタイミングで処理をする設計になっています。動画再生はExoPlayerを使っています。
━━iOSとAndroidにおいて、どんな技術的チャレンジに取り組まれてきたんでしょうか。
堀江 『TIPSTAR』のネイティブアプリどちらにも共通しているのが、ガチャの部分はUnityを入れて開発しているところです。ゲーム系アプリであれば、Unityでの開発は珍しくもないかもしれませんが、非ゲーム系で取り入れているとなると、あまり例がないかもしれません。理由は、プロダクトにガチャがあり、リッチに表現してユーザーに楽しんでもらいたいからです。
また、アプリ開発において、2019年4月頃からUnityをネイティブアプリ開発において、部分的に扱えるようになったのも大きいです。『TIPSTAR』は非ゲームとゲームを融合した新ジャンルのアプリだと考えていますので、OSの影響を受けないところはリッチに見せるためにもUnityの最新の機能を使って対応していこうということになりました。
山田 ネイティブでは出すのが困難な演出が、Unityなら実現しやすいんですよね。
寺田 ユーザーに体験してほしい世界観を実現するためにはリッチなアニメーションがベストだろうと。そのための方法として、Unityでの開発を判断しましたから。
━━Unityを非ゲーム系のアプリで組み込むのは珍しいですよね。他にも工夫やチャレンジはあるのでしょうか。
堀江 そうですね。車券購入画面では、負荷でアプリがクラッシュしないように、見えている部分だけにメモリを使うという工夫もしています。こういったリスト型のUIを実装する時は、iOSではTableViewという特定のパーツをリサイクルできる仕組みを使うのですが、『TIPSTAR』の場合は一つの領域に様々な情報を詰め込んだり、枠やグラデーションを多用したレイアウトであることもあって、非常に実装しづらかったんですね。StackViewというものを使えば実装自体は楽なのですが、そちらは全てのデータを一度に処理してしまうので、車券を大量に購入するとクラッシュしたりパフォーマンスが悪くなってしまう可能性が高かった。そのため、手間がかかるのは承知の上で、一つ一つカスタムパーツを作りながらTableViewで実装を行いました。
山田 Androidだけの挑戦でいうと、Canvasからアニメーションさせているところがあります。『TIPSTAR』ではゲームで見られるようなUIパーツが光輝く演出が多様されています。これらは当然Androidネイティブ開発のコンポーネントには用意されていないため、低レイヤーな部分から描画していく必要がありましたので、全て開発しました。
堀江 他にも、レース結果を確認できるリザルト画面では、様々なアニメーションをつけています。車券が少し当たったか、たくさん当たったかによって演出を切り分けていて、こういったアニメーションは、ネイティブだとあまり多用しないのですが、「レース結果をみる」というユーザーの気持ちが盛り上がる部分をリッチにみせたいという背景があって、一部に動画を取り入れたりコードでパーツを動かすようにしたりと工夫している部分です。
山田 そうですね。あとは通信方法に合わせた自動画質選定もAndroidアプリには搭載されています。例えば、Wifiは高画質、4Gの場合は低画質というように、環境に合わせて快適に動画視聴ができるよう工夫しています。
堀江 サーバ側で、高画質、中画質、低画質という3種類の動画データを流していて、普通は勝手に選択されてしまうのですが、山田さんはそこに手を入れて、最初の表示画面では低画質が選ばれるようにコードで実装しているんですよね。iOSはまだ回線の種別まではできていないので、今後取り組んでいきたいところではあります。
━━なるほど。様々な工夫が盛り込まれているんですね。ちなみにみなさんは開発をしているとき、どんなことを心掛けていますか。
堀江 デザイナーから上がってきたデザインを、一ピクセルのズレもないように表現できるように気を付けています。またプラットフォームの差がないように、UIや挙動も同じように作っています。
山田 デザインのレギュレーションがiOS基準なので、AndroidはAndroid向けにチューニングしなおして開発をしています。表示サイズもiOSと異なりますし、文字サイズは画面サイズが大きい端末でも小さい端末でもそのままの大きさで表示される実装になっているので、小さい端末だとテキストが収まりきらないということもあって、少し苦労しましたね。
━━それはどのように解決を?
山田 場所によって細かくカスタマイズしたり、文字を小さくしてみたり。スケールを自動調整してくれるカスタムパーツを作って対応しました。
堀江 iOSのほうでもデバイスが異なると端末の表示サイズが変わるため、Androidと同じように自動調整するカスタムパーツを搭載しています。
山田 その他で心掛けているのは、ユーザーが快適にプレイできる環境を作るということですかね。
堀江 そうですね。もともとは車券購入のシステムとしてカートシステムを導入し、一度サーバ側にカートの中身を渡す仕組みにしていたのですが、色々と試行錯誤した結果、カートシステムの使用をやめました。サーバ側ではなくクライアント側でデータを持つことにしたんです。そのほうが処理も早く、ユーザーがスムーズに遊ぶこともできるので。
━━ユーザーに見えない部分も、色々と苦労されて開発されているんですね。そこまでやる原動力とは、一体…?
堀江 私はデザイナーさんの「これは無理ですよね…?」という難解なオーダーを実現できたときも手応えを感じます(苦笑)。『TIPSTAR』はUIが特徴的で一番力を入れているところでもあるので、可能な限りは応えたいと思っています。
山田 確かにそうですね。それはどのエンジニアも同じ思いを持っていると思います。あとはガチャの開発でUnityを取り入れるというように、新しい技術チャレンジができる環境ですね。
堀江 手探りで開発していく中で、上手く入れ込むことができたので、そこは面白かった部分でもありますよね。
寺田 苦労して開発している結果、『TIPSTAR』が少しずつですがSNS等で話題にしていただけるようになって手応えを感じています。またユーザーから、エンターテインメント性の部分で新しい試みだと評価いただけているのは純粋に嬉しいですね。
堀江 競輪という公営競技の敷居を下げて、たくさんのユーザーに気軽に楽しんでいただけている実感もありますし、そこは開発者冥利に尽きると思います。公営競技に関するサービスを提供する側、というのは貴重な経験ですよね。
寺田 確かに。これまで私自身も競輪に触れてこなかったので、仕事を通じてドメイン知識が増えているのは面白い経験だと思います。
━━最後に、今後チャレンジしたいことについて聞かせてください。
山田 決済手段の追加ですね。今は銀行口座からの引き落としとクレジットカード決済のみなのですが、他にも決済機能を強化して、より多くのユーザーの方に楽しんでもらえるようにしていきたいです。
堀江 そうですね。それが目下の目標でもあります。また、将来的には様々なジャンルのコンテンツを扱う展開も視野に入れているので、その基盤となる『TIPSTAR』を粛々と開発し、実績を積み上げていきたいと考えています。