Hatamoto 〜モバイルアプリに関する情報を一元管理するためのWebアプリケーション〜

こんにちは。元モバイル基盤部(現クックパッドマートプロダクト開発部)の大川(@aomathwift)です。

クックパッドでは、レシピサービスのクックパッドアプリだけでなく、生鮮 EC サービスのクックパッドマートをはじめ、複数の iOS アプリを開発しています。

複数のアプリを開発する上で、機能そのものの開発以外に開発者が気にかけないといけないことがいくつかあります。 例えば、各種証明書の有効期限、ライブラリの選定やバージョンアップなどです。開発者はこれらの関心事に対して、全てのアプリで同じように注意していなければいけません。

クックパッドでは、「Hatamoto」という Web アプリケーションでこれらのアプリに関する情報を一元管理しています。 本記事では、iOS アプリにまつわる情報管理の中で生じる課題と、Hatamoto がそれをどのように解決しているかを紹介します。

Hatamoto 導入前の課題

クックパッドでは、モバイル基盤というグループが App Store Connect をはじめとするアプリ開発に必要なサービスのワークスペースの管理者としての役割を担っています。アプリの証明書の発行等のオペレーションは、モバイル基盤グループで行っています。

このモバイル基盤グループに所属するエンジニア目線で、Hatamoto 導入前は社内アプリの証明書管理やライブラリの更新に関していくつかの課題がありました。

開発者が自発的に証明書の有効期限に気づく必要がある

iOSアプリでプッシュ通知を送信するには、Apple Push Notification Service(以下 APNs )の証明書が必要です。この証明書は1年という有効期限を持つため、継続的にプッシュ通知を送り続けるためには期限が切れる前に更新して差し替える必要があります。 もしこの証明書の差し替えを忘れて有効期限を過ぎると、アプリのプッシュ通知が突然届かなくなってしまいます。 そのため、アプリ開発者達は APNs 証明書の有効期限を把握し、期限が切れる前に自発的にモバイル基盤グループに更新を依頼する必要がありました。

また、クックパッドでは、Apple Developer Enterprise Program に加入しており、社内で動作確認するためのアプリを配信するのに利用しています。この Apple Developer Enterprise Program を使ってアプリを配信する際にも、通常の Apple Developer Program を使った配信と同様に Provisioning Profile が必要になります。 もしこの Provisioning Profile の更新を忘れて有効期限を過ぎると、社内ですでに配信済みだったアプリが突然利用できなくなるという、開発を進める上での問題が起こります。さらに、通常の Apple Developer Program で作成した App Store 配信用の Provisioning Profile も、更新を忘れると App Store にアップロードするバイナリをビルドできない問題に直面します。 したがって、これらも APNs 証明書と同様に、期限が切れる前に気づいて更新を依頼する必要がありました。

更新が必要なライブラリを使い続けていることに気づけない

クックパッドで開発している iOS アプリでは、オープンソースのライブラリから社内ライブラリまで、様々なライブラリを利用しています。 モバイル基盤グループでは、あるライブラリで脆弱性を含んだバージョンがリリースされたり、既存の挙動を壊すような問題・変更のあるバージョンがリリースされたりした場合に、そのライブラリを使用しているアプリの開発者に迅速に共有したいという需要がありました。*1

しかし、各アプリで使われているライブラリとそのバージョンを常に人力で追い続けることは難しく、利用しているアプリ側で実際に問題に直面してから対処するということが多いのが実情でした。

Hatamotoの機能

上記の課題の解決をモチベーションに、Hatamoto には以下の機能が実装されています。

証明書の有効期限を監視し、期日が近づいたら Issue を起票する

各アプリの APNs 証明書に加え、Provisioning Profile ・開発者証明書の有効期限を一覧して管理できます。

また、この収集した有効期限を毎日定期実行されるジョブで監視し、有効期限が1ヶ月以内に近づいた場合にモバイル基盤グループへの依頼用リポジトリ宛に更新依頼 Issue を自動で立てることができます。

各アプリで使われているライブラリを一覧する

アプリごとに、使用しているライブラリとそのバージョンを一覧できます。 iOS はライブラリの管理方法が SwiftPM、CocoaPods、 Carthage と複数存在するので、それぞれに対し異なる収集方法で収集しています。 また、この収集した情報を活かし、「このライブラリを利用しているアプリ」も参照できます。 この機能は gem_collector にインスパイアされています。

ライブラリを利用しているアプリに向けての一括アナウンスをする

これもまた gem_collector にインスパイアを受けた機能になりますが、特定のライブラリを使用しているアプリの開発リポジトリに対して、一斉に Issue を起票することができます。

これは、ライブラリ側に問題が見つかり早急にアップデートを依頼したい場合や、社内ライブラリに破壊的な変更が加わった場合などに利用される想定で作られています。

ちなみに Hatamoto という名前は、モバイルアプリにまつわるデータを「監視する」という意味合いから監視役→衛兵→戦国時代における武将の近衛兵=旗本という流れで名付けられています。

各機能の実現方法

各機能は以下のように実装しています。

証明書の有効期限管理

各証明書の有効期限管理は、それぞれ以下の図のような流れで実現しています。

APNs 証明書の更新の際は、有効な証明書の有無を確認し、必要に応じて新規作成するという作業をまとめて行う fastlane の pem というアクションを利用しています*2

この機能を利用するためには、Apple Developer の AppManager 以上のユーザーでログインする必要があり、そのログインの際に他要素認証が求められることから、APNs 証明書の更新はモバイル基盤グループのメンバーによって手動で実行されています。 この更新の際、作成された証明書を Amazon S3 (以下 S3 )のバケットにアップロードするようにしているので、その中身を見て有効期限をチェックしています。

Provisioning Profile・開発者証明書の有効期限の取得には App Store Connect API を使っています。

有効期限が近づいているかどうかは、毎日定期実行されるジョブ*3で今日の日付と有効期限を比較して確認しています。

使用ライブラリの収集

各アプリが利用しているライブラリの取得は、パッケージマネージャーごとに異なる方法で実現しています。

Carthage、SwiftPM

GitHub API を使って各リポジトリ内の Cartfile.resolved、Package.resolved の中身を取得しパースしています。同じく GitHub API 経由で、利用しているライブラリの最新バージョンを取得しています。

CocoaPods

CocoaPods で解決されたライブラリのリストとそれぞれのバージョンが記述される Podfile.lock には、そのライブラリのリポジトリ URL が記載されません。そのため、SwiftPM や Carthage と同様に Podfile.lock の中身を基に GitHub API を利用してライブラリの最新バージョンを取得するというのは難しいです。 したがって、利用している CocoaPods ライブラリの取得及び最新の podspec の情報の取得は、各アプリのメインブランチの CI で実行するようにしました。ここで収集した情報を S3 にアップロードし、アップロードされた情報を同様に Kuroko2 のジョブを定期実行して取得し DB に登録する、という流れにしています。

Hatamoto を実際に運用してみて

Hatamoto を実際に運用してみて、最も良かったのは証明書の有効期限を気にする必要がなくなったことです。証明書は各アプリの管理者がダウンロードして差し替えることになるので、管理者であるモバイル基盤グループのオペレーションが減りました。

また、各アプリが使っているライブラリを一覧できるというのは、思いの外管理者以外の開発者の目線から役に立つ場面がありました。 たとえば、新しくライブラリを導入しようとしたときに、社内にそのライブラリを使っているアプリが他に無いかを調べ、導入方法を確認する、といった活用例がありました。

逆に、ライブラリを利用しているアプリに向けての一括アナウンスは未だ活用されていません。対応が必要な問題がみつかったときに、各アプリで開発者側が自発的に Issue を立てて対応していることが多く、開発者達の対応力の高さ故にあまり需要がない機能となってしまいました。

おわりに

この記事では、アプリの各種証明書や各プロジェクトが依存している開発ツール・ライブラリなど、 iOS アプリに関する情報を一元管理するための Web アプリケーション「Hatamoto」を紹介しました。 このツールのおかげで、 iOS アプリを開発していく上で面倒となる管理部分が効率化できています。App Store Connect API の機能が増えれば、証明書の生成フローなど更に自動化できる部分が増え、より便利に利用することもできそうです。

この Hatamoto は主に App Store Connect API と GitHub API 、fastlane を使って比較的単純な処理で実現されています。複数アプリにおける証明書等の情報管理に悩む方は、Hatamoto のようなWebアプリによる管理を試してみてはいかがでしょうか。

*1:社内ではアプリごとにライブラリの更新を監視するスクリプトを自前で書いて週次で実行していましたが、利用するバージョンを固定している場合や、更新の緊急性が高い場合にこれが機能しないという事情がありました。現在は、Renovate のようなツールを利用するのも解決手段の一つだと思います。

*2: App Store Connect API には証明書を作成する機能がないため、作成処理を完全に自動化することは現状できません

*3:クックパッドで利用されている Ruby 製の Web ベースのジョブスケジューラー Kuroko2 を利用しています