今はSwiftが99パーセント

崔正煜氏(以下、崔):それでは、これからLINEマンガのiOSのアプリ開発についてお話しできればと思います。

簡単に私の紹介をしますと、2007年から3年ほどJavaの経験をして、2010年ぐらい、ちょうど日本でスマホが広がり始めたころにAndroidとiOSについて覚えて、2010年からiOS/Androidの開発をしてきました。それから2014年にLINEに入社して、LINEマンガに配属されて、今までずっとLINEマンガのiOSアプリの開発を担当しています。

今のLINEマンガのiOSアプリ版の開発環境ですが、直近のリリースではXcode11.5ベースで行っていて、iOS 14がもうすぐリリースされるので、それに向けてXcode12に、今はBetaですが、並行で進めています。

LINEマンガはもう7年目を迎えていて、当初は当然Objective-Cから始まったプロジェクトでしたが、SwiftがリリースされたころからSwiftへの移行が進んでいて、今はSwiftが99パーセントを占めている状況です。アーキテクチャとしては、MVCとMVVMが混在している状況で、よく使っているフレームワークはRxSwiftとRealmとSnapKitなどがあります。

最近コロナの影響もあって、ほぼ在宅で作業していて、その中でiOSのエンジニアたちがどのように1週間を過ごしているのかを簡単に説明しようと思います。

定期的に行うイベントとしては、毎日15分、1週間に1回、1時間ぐらいLINEマンガのエンジニアが集まって、今やっているタスクの実績や計画を簡単に共有する場があります。

タスクはアトラシアンのTrelloで管理しています。あとは週1で1時間ぐらい、企画、デザイン、QA、開発のみんなが集まって、状況の共有や進捗の確認、今後のタスクの紹介などを行います。それから週1の1時間から2時間ぐらい、iOSエンジニアだけでiOSだけの話に絞って、タスクや悩み、最近のトレンドを雑談交えて話し合う場があります。

あとは人やアサインされているタスクによって異なりますが、各タスクにアサインされている企画、デザイン、QA、エンジニアが集まって、毎日15分ぐらい情報共有なり相談なりを話し合ったり、Ownershipをもって自主的に進めています。

その他は、毎日クラッシュレポートやユーザーレビューなど、いろいろなログを確認しながら随時対応したり、あとはそれ以外は各メンバーが自分のペースで開発や勉強を自主的に進めているような、十分裁量が与えられている環境だと思います。

3つの開発の進め方

ここからは、開発の進め方についてお話ができればと思います。この3つの観点から紹介しようと思います。まずは一番一般的な進め方ですが、企画・デザインベースの進め方は、さまざまなデータを基に施策を練って、企画・デザイン・開発が集まってそれを検討して、そこで案件が決まったら担当を決めて、各担当者たちが自主的に進めるという感じです。

先ほども話していた、デイリーミーティングで議論しながら、方向性を確認したり、デモを見せ合って開発を進めます。

次はエンジニアメインで進めるやり方で、Androidもそうですが、常に新機能がリリースされていて、エンジニアがいつも何がおもしろいか、活かせる機能がないかを話し合っていて、そこでアイデアを出した人が軽くプロトタイプを作って、デイリーミーティングやウィークリーミーティングでデモを見せたり、フィードバックをもらって改善を重ねたりして、エンジニア主導でプロダクトまで持っていくというスタイルです。

ユーザーにうれしかったり新しい体験になったりするのであれば、みんな快く受け入れてくれる雰囲気で、エンジニアも、自分のアイデアがプロダクトになるところに楽しみを感じるので、積極的に進めているスタイルです。

そのエンジニアが出したアイデアがプロダクトになった事例をいくつか紹介させてください。まずはApp Storeからインスピレーションされたものですが、PUSHとPOPのときに、カバーイメージを維持したまま画面遷移できるようにしているもので、ユーザーの視線を遮ることなく、スムーズにアプリを使ってもらえるようになった事例です。

次はダークモードで、ダークモードはiOS 13から正式に導入されていましたが、実はLINEマンガはiOS 13が発表される前から実装していました。ダークモードはmacOSから導入されていて、iOSでもほしいなということで、まず色コードをプログラム的に変えるような実装を入れて、デザインチームに協力してもらいながら完成させたものです。

なのでLINEマンガでは、iOSのバージョンに関係なくダークモードを試すことができました。今もできます。

次はFaceTrackingですね。実際に使われる比率はそんなに高いとは言えませんが、iPhoneのX以降のTrueDepthカメラという機能を利用して、Viewerの中で指の操作なしでページを送ったりViewerを閉じたり、ウインクや舌を出すということで操作できる機能です。満員電車とかでは注意が必要な機能ではあります。

その他にもUI的なところだけではなく、サードパーティのオープンソースライブラリへの依存などを減らしたり、個人的な興味もあり、ライブラリは使わず自分たちで作ったりもしています。APNGやZIPなどの解析は、ライブラリを使わず自分たちで自作したりしています。

あと、LINEマンガのアプリの中にはLabsというメニューがありまして、まず試したい機能はそこに集約させて、ユーザーの行動データやフィードバックをもらって、改善していきます。先ほど紹介したダークモードもLabsの中に入っていましたが、好評だったので正式メニューに昇格されたケースですね。

続いてユーザーベースでの進め方ですが、カスタマーサービス、ユーザーレビュー、クラッシュレポートを常にモニタリングしていて、ユーザーが不便に感じるところは最優先で、100パーセント解決できるように心がけています。

一方、要望についても積極的に取り入れるようにしていて、AppSwitchのときにアプリの中が見えるのがいやだとか、キャッシュを消したいとか、自動ロックを解錠したくないとか、そういった要望を積極的に入れて、今はプロダクトに入っている状況です。エンジニアも1人のユーザーなので、自分の要望があれば、入れやすい環境ではあります。

この3つの進め方をまとめますと、何度も自主的や主導という言葉が出てきましたが、各メンバーがオーナーシップをもって、責任をもって積極的に、能動的に動くこと。ユーザーが第一、ユーザーへの思いやりがある。あとはエンジニアたちも自分たちが楽しめる環境であるということに、まとめられると思います。

今後のiOSの課題

今後のiOSの課題は、iOS 14の新機能がいろいろあるので、それを入れたり、UIテストが少し進んではいますが全般的に使われていないので、もっと広げてQAの工数を減らしたり品質を担保したり、ユーザーがストレスなく気持ちよく読めるようにViewerの改善を進めたりすることなどあります。

LINEマンガは「新しい1ページを」というのがキャッチフレーズ的なものですが、これに則って話をしますと「LINEマンガのiOSアプリの新しい1画面を一緒に作りませんか?」というメッセージをお送りしたいと思います。お待ちしております。

私の話はここまでです。ご清聴ありがとうございました。

Androidアプリの開発について

関童氏(以下、関):ではここからは、私がLINEマンガのAndroidアプリの開発についてお話しします。まずは自己紹介ですが、名前は関童と申します。下は私の名前の中国語と英語の書き方です。

出身は中国の天津です。スライドの左側は中国の地図なんですが、天津は中国の東側で、北京に近いところですね。一応天津から東京まで飛行機でだいたい2時間半ぐらいの距離です。右側の写真は天津の夜景です。ちなみに天津飯は天津料理ではありません。

次に、私は2008年に、Javaのシステムエンジニアとして日本に来ました。その後2011年にAndroidを開発し始めて、そのときはまだAndroidは1.6時代でしたね。そして2015年2月にLINE株式会社に入社して、同時にLINEマンガチームに加入しました。ですので、今まで5年以上LINEマンガの開発を担当しています。

開発環境

ここからは、LINEマンガのAndroid開発の話をします。まずはAndroid開発環境から紹介させてください。IDEはもちろんAndroid Studioを使っています。今のバージョンは4.0.1です。開発言語はJavaとKotlinの両方を使っていて、一応古いソースコードはすべてJavaで書いてありますが、新機能の開発とテストコードはすべてKotlinを使っています。

実際に今は、古いソースコードを置きかえる作業をしていて、下のGitHubのグラフを見ると、今のソースコードの中でKotlinは4.7パーセントしかないのですが、年内には10パーセントを目指しています。

Out Of Memory問題

続きましてAndroid機能において、最近は企画案件以外では何をやっているのかを紹介したいと思います。まずはOut Of Memoryの改善から紹介します。なぜOOM問題を解決する必要があるのかというと、ご存じのとおりLINEマンガはアプリ内に画像表示がとても多いためです。クラッシュレポートを見る限り、Androidクラッシュの7割以上はOOM問題でした。Android全体のクラッシュ率を下げるためにはOOM問題を改修すべきと思ったので、OOM問題を改善しようと決めました。

普通はOOM問題を解決するために、下記の3つの手段があると思います。まずはAndroidマニフェストのある属性「android:largeHeap」をtrueに設定すること。2番目はBitmapを使ったあとにすぐ解放すること。リサイクルの話ですね。最後はBitmapを適切なinSampleSizeに変更することです。

基本的にこの3つの方法で修正したらOOM問題は大きく改善できますが、ただLINEマンガのAndroid版は、上記の対策はすべて実施されており、これ以上対応するためには他の方法も必要だになります。

そこでAndroidのチームでは下記の4つの対策を入れました。まずはメモリリークはOOMが発生する1つの大きな原因なので、メモリリークを検出するために、SquareのLeakCanaryを使って、リークする場所をすべて洗い出して、問題があるところを修正しました。2番目の対策は、contextオブジェクトをWeakReferenceとしてアクティブやスレッドに渡して、メモリリークを回避するように修正しました。

3番目の対策は、アクティビティとフラグメントを閉じたときにメモリを解放しやすくするために、すべてのメンバー変数とViewオブジェクトをnullにしました。最後は、アプリがバックグラウンドにいった瞬間に、強制的にGCを実施することも追加しました。

その改善の結果、Android 8系以上のOOMはほぼなくなりました。つまり全体のOOM件数は以前より半分に減少したということです。

Coroutineの導入

続いて、Androidチームが最近もう1つやっていることは、Coroutineを導入することです。これはまだ進行中の案件ですが、Kotlin化の作業に伴って、Coroutineを導入することも考えております。目的は、まずはソースコードをシンプルにすることと、あとは効率向上のためです。

サンプルコードを使って改善した箇所を説明します。まずソースコードをシンプルにすることについては、例えばこういう仕様があったときに、APIを叩いてユーザー情報を取得してから画面に設定したい場合、普通は左側のソースコードになります。getUserのAPIを叩いて、そしてCallbackでuserwriteに切り替えて、最後にテキストViewにユーザー名を設定するような流れです。

しかしこれをCoroutineを使った場合は、右のように、コールバックとスレッドの切り替え作業はすべていらなくなり、3行だけで終わります。ソースコードはけっこうシンプルになりました。

次に効率向上について、同じくサンプルコードを使って説明いたします。例えばapi.getA()とapi.getB()を呼んで、オブジェクトAとオブジェクトBを取得して、そしてAとBをマージしたい場合は、getA()とgetB()のレスポンスのどちらが先に来るかが事前にわからないので、左側のコードのように、2つのAPIを順番で呼ぶかたちが採用されていました。まずオブジェクトAを取得してオブジェクトBを取りに行って、Bを取りに行ったあとにAとマージする流れですね。

ただ、このやり方だと、実行時間はgetA()+getB()となります。本来は並行して実行できる処理が、順番に実行されてえ効率がちょっと悪くなってしまいます。

これについては、Coroutineを採用すれば、簡単に解決できます。右側のソースコードはCoroutine内で実装していますが、こうすると簡単にオブジェクトAとBを取得できて、あとはマージできます。右側のソースコードは処理の時間は、getA()とgetB()の中でより時間のかかったほうとなるので、実行時間は、左側のソースコードよりだいたい半分になりました。Coroutineを導入することで、アプリが高速化されると思います。

100パーセントKotlinに

最後は今後やりたいことの話です。今考えているのは、主に3つのタスクです。まずはさっき話したKotlin化のタスクです。最終的な目標は、完全にJavaを廃棄して100パーセントKotlinにすることです。2番目のタスクは、UX向上のため、マンガ閲覧用のViewerのパフォーマンスを改善しています。

3番目は、今LINEマンガのAndroid版はMVCとMVVMのパターンが利用されていて、今後は全部をMVVMに切り替えることを考えています。

Androidの話は以上となります。ありがとうございました。