自己紹介とアジェンダ

樫原翔太氏(以下、樫原):「iOS エンジニアが KMMで2つのアプリのログイン処理を共通化した話」を、ウォンテッドリー株式会社の樫原が発表します。

(スライドを示して)自己紹介はこちらです。ぜひ、Wantedlyのプロフィールを使ってください。

今日の発表の目的ですが、ふだんKMMの勉強会に何を期待して行くのか、参加する方の心理を考えてみました。

KMMの魅力が、クロスプラットフォーム技術にあるのはなんとなくわかっているけれど、「では、実際にどういうところで使っているの?」という部分を知りたいのではないかと解釈して、今日は発表をしたいと思います。

アジェンダです。KMMを利用したログイン処理を今回実装したので、その話をします。 実装した機能がどういうものなのかという概略の話と、なぜ技術選定としてKMMを利用したか。その過程でどういう議論があったのか。最後に、コードを少し紹介したいと思います。

2つのアプリ間でのログイン引き継ぎ機能を実装

まず、ログイン処理を少し詳しく説明します。我々はWantedlyの名を冠する2つのアプリを作っています。みなさんの転職を支援する「Wantedly Visit」と、みなさんのプロフィールと個人間のつながりを充実させる「Wantedly People」というアプリです。

それぞれリリースしてからもう何年も経っています。既存のアプリでもログイン処理などは入っていますが、加えて「アプリ間のログイン引き継ぎ機能」を実装することになりました。

これがどういうものかというと、片方のアプリを使っているユーザーが、もう1つのアプリを新しくインストールした時に、スムーズにログイン状態に移行できる機能です。

(スライドを示して)どういう動きをするかというと、前提として、2つのアプリで同じWantedlyのアカウントが使えます。片方のアプリをインストールしてログインをした時に、①のトークンをローカルに取得します。それを2つのアプリが共有する領域に保存しておきます。新しくもう一方のアプリがインストールされた時に、トークンを読み込んで、簡易ログインする、という処理の流れになっています。

もう1つ、iOSとAndroid、それぞれにこの機能を実装する必要があるので、VisitからPeople、PeopleからVisitという経路も、それぞれ発生します。なので、その4つの機能を各アプリに実装します。

(スライドを示して)そのため、①と②の引き継ぎ元の準備のための処理と、③と④の引き継ぎ後のための処理を、それぞれ2つのアプリと両OS、全部で4ヶ所にネイティブで実装する必要があります。

そこで、KMMを使って重複したコードをどれだけ減らせるか、KMMを使って減らしたほうがよいのではないかという話で進めてきました。

KMMを使うメリットと実装の進め方

まず、なぜKMMを使うのか。サービス全体で見た時に、2つのアプリは重複するロジックのコードが多いです。

今回の機能の場合、2つのアプリにそれぞれSwiftとKotlinで同じようなロジックを実装するのと比べると、KMM(Kotlin)でロジックを実装するほうが、コードの量が1/4になるメリットがあります。

大まかにこのようなメリットがあるため、「KMMを利用しよう」とチームに共有をしました。

また、私はiOSアプリエンジニアなので、この機能にKMMを利用するために、KMMをより知っているAndroidアプリのエンジニアと詳しくディスカッションをしました。さらに、会社全体の技術の採用や技術選定の責任を担っているアーキテクトとも交えて、3人で議論を進めていきました。

話した内容は、KMMにするメリット・デメリットの整理です。メリットだけではなく、ライブラリとして別のリポジトリで管理することによるデメリットもあります。

次に、ライブラリに含めた機能の責務の設計。UseCaseとしてライブラリに提供するのか、ViewModelまで含めてライブラリとして提供するのか。あるいは、expect/actualというOS依存のコード部分に持たせるものはあるのかないのか、あるのであればどういう機能なのか。

ほかにも、KMMライブラリの置き場所の設計です。どういうふうに、iOSアプリとAndroidアプリに配信するのか。最後に、これを誰が実装するのかなどといった話を大まかに議論して、この機能の実装を進めていきました。

どのようなコードを書いたのか

最終的にどういうコードを書いたのか。(スライドを示して)まず前段の引き継ぎ元のアプリです。

これは①と②で、トークンの取得とトークンの保存を、UseCaseで実装しています。①でsuspendの関数を使っています。iOSだとSwift5.5からasync/awaitが使えますが、Kotlinはすでにコルーチンが使えるので、非同期呼び出しを同期的に書けます。

2番目に最初のトークンをAPIから取得して、3番目で共有している保存領域にトークンを永続化するUseCaseを作りました。これだけです。

もう1つ、今度は利用側、つまり引き継ぎ側です。こちらではログインの処理を行っています。共有している永続領域から引き継ぎのための情報、先ほど保存した情報をauthentication関数で定義して取り出して、ログインのためのAPIを叩くかたちです。

これをそれぞれ2つのアプリにSwiftとKotlinで両方書くのと、ここだけをKMMだけで書くのではソースコードの量が違うという話です。

取り組みのまとめ

まとめです。WantedlyでのKMMの導入事例の一部を紹介しました。サービス全体の中で重複したコードを削減する際に、KMMはかなり効果的だと思っています。

また、先ほど議論したという話をしましたが、KMMの利用に際して、iOSアプリエンジニア、Androidアプリエンジニアの相互のディスカッションがかなり重要です。片方の、例えばiOSアプリエンジニアがこれを推してよしとしても、やはりAndroidアプリエンジニアの協力なしには作れないですし、その逆もまたしかりです。

というわけで、僕の発表は終わります。ありがとうございました。

質疑応答

司会者:樫原さん、ありがとうございます。1点、「iOSからsuspendをどうやって呼ぶのか?」という質問をいただきました。いかがですかね。

樫原:クロージャーで呼び出すことになります。なので、ふだんiOSエンジニアがよく書くような、APIでのリクエストっぽい見た目の呼び出し方になります(笑)。

司会者:もう1個、「両方のアプリは、もとからKMMを利用していたのでしょうか?」という質問に関してはいかがでしょうか?

樫原:いいえ、違います。VisitではKMMを利用していましたが、PeopleではKMMを利用していなかったので、まずそこが違います。あともう1つ、VisitでKMMの利用はしていましたが、Visit iOSとVisit Androidの間でのソースコード共有だったので、iOSのVisitとPeople、AndroidのVisitとPeopleと、4つのアプリを共有するKMMの利用は今回が初めてで、また新しくライブラリをイチから導入しています。

司会者:なるほど、ありがとうございます。ほかの方が質問などなければ、樫原さんの登壇は終了いたします。樫原さん、ありがとうございました。

(司会者拍手)

樫原:ありがとうございました。