見出し画像

iOS アプリの配信作業を「極限の一歩手前」まで簡単にした #Zaim

お元気ですか。Zaim の watura です。

突然ですが、iOS アプリを App Store に申請する際などに発生するバイナリのアップロード作業で、ひたすら苦しめられた記憶はありませんか?

iOS アプリの証明書やプロビジョニング周りの作業、および App Store への申請を含むバイナリの配信は、昔に比べたらかなりマシになったとはいえ非常にややこしいですよね。Zaim では、その辺りを超シンプルに管理し、面倒な作業とオサラバしました。

先日クックパッド開発ブログで紹介された以下の記事が「極限まで簡単」であれば、これからご紹介するやり方は「極限の一歩手前まで簡単」な方法です。

Distribution, Ad-hoc は fastlane match を活用

まずは、App Store に申請するための Distrobution プロファイルや、特定多数の端末に配信する Ad-hoc プロファイルを使ってアプリを配信する場合について説明します。

こうしたバイナリ配布用のプロビジョニングや証明書の管理は、手動でやろうとすると複雑極まりありません。これらはタスクランナーである fastlane と CI(Continuous Integration:継続インテグレーション)ツールである Bitrise を使うことで、大幅に簡単になりました。

具体的には、Zaim では Bitrise 経由で fastlane match を実行しています。fastlane match は、まさにこうしたファイルをリポジトリで管理するためのツールです。

何が嬉しいことがあるかというと、

チームで共通したプロビジョニングや証明書が使える
キーチェーンから証明書をエクスポートするなど面倒なことはしなくていい
AppID やデバイスも追加できる
Development, Ad-hoc, Distribution 全部のファイルを管理できる
暗号化された状態で保存できる

というような点になります。いろいろ便利です。詳しくは公式のドキュメントを確認してください。

重要なのは、共通のプロビジョニングや証明書を簡単に、かつセキュアに共有できるということです。

なお、そもそもなぜ Bitrise と fastlane の組み合わせを採用しているかについては、以前書いたこちらの記事で説明しています。

Development は Automatically Manage Signing を活用

一方で、アプリ開発時においては、アプリをデプロイできるようにする必要はありません。最近の Xcode では、こうした場合にプロビジョニングプロファイルや証明書の管理作業を実質的にスキップできる機能がついています。それが「Automatically Manage Signing」です。

設定の Automatically Manage Signing にチェックを入れると適用されます。Zaim は基本的に Development 段階では全員 Automatically Manage Signing を使っています。

Distribution, Ad-hoc と Development の自動切替

以上をまとめると、

Development:Automatically Manage Signing
Ad-hoc: fastlane match
Distribution: fastlane match

というように、バイナリ配布先によってプロビジョニングプロファイルや証明書の管理に使っているツールが二種類に分かれています。

通常、この二つを併用しようとすると Development 設定の時は Automatically Manage Signing、それ以外の時は fastlane match とわざわざ切り替えなくてはならず、とても煩雑です。 

Zaim では、これらを自動で切り替えられるようにしました。具体的にどういったコードや設定で実現しているのかを、これからご紹介します。

まず Xcode の設定は、上記の画像のように Xcode Automatically Manage Signing を有効にしています。このままビルドすれば、Development 用のバイナリとして端末やシミュレータに配布されます。

次に Ad-hoc 用のバイナリの取扱いです。以下は、実際に使っているコードを少しシンプルにしたものです。 

desc "Build"
  private_lane :_build do |options|
   # ①
   sync_code_signing(app_identifier: ["bundle_identifier"], readonly: true, type: "adhoc")
   # ②
   disable_automatic_code_signing(
      use_automatic_signing: false,
      targets: ["target"],
      code_sign_identity: "iPhone Distribution",
      team_id: ENV["sigh_bundle_identifier_adhoc_team-id"],
      profile_name: ENV["sigh_bundle_identifier_adhoc_profile-name"]
    )
    
    gym(export_method: 'ad-hoc', scheme: "scheme")
    _deploy(options) # deploygateにdeployするときに色々オプションとか設定してる、専用レーンです。slackにいい感じに投稿とかもします
  end

このうち、重要なのは ①, ② の部分。まず、① は MatchFile などで設定した Git リポジトリから証明書やプロビジョニングプロファイルを取得する Action です。 

sync_code_signing(app_identifier: ["bundle_identifier"], readonly: true, type: "adhoc")

app_identifier が bundle_identifier の distribution provisioning などを取得してくれます。なお、readonly: true としているので、bundle_identifier のプロビジョニングプロファイルが登録されていない場合はエラーが出ます。

これを実行すると、sigh_bundle_identifier_adhoc_team-id や、いくつかの環境変数に取得した結果を保存します。これらの環境変数には、プロビジョニングプロファイルがどこに保存されたか、名前、app_identifier などが含まれています。

この環境変数を②の disable_automatic_code_signing で使います。その名前の通り、automatic code signing を無効にします。この Action を実行すると Xcode の設定が書き換わり、profile_name に指定したプロビジョニングプロファイルを使うようになります。

ここでは、対象とする target, identity, team id, profile name を match で取得した値を使い指定します。

ENV["sigh_bundle_identifier_adhoc_team-id"] # Team id
ENV["sigh_bundle_identifier_adhoc_profile-name"] # Profile name

このように指定したプロビジョニングプロファイルを使わせることで、Bitrise 上で Xcode が自動で管理しているプロファイルや、Apple ID の連携を考慮する必要がなくなります。

これで、このプロジェクトファイルは Ad-hoc 用の設定を使うようになっています。あとは Ad-hoc としてビルドして、デプロイすれば終了です。

なお、この Lane をローカルで動かした後は、Automatically Manage signing がオフになり、Ad-hoc 用の設定になっていることに注意してください。

App Store への申請は fastlane deliver を活用

App Store に配布する Distribution 版も、基本的には Ad-hoc 版と同じ手順です。ただし、二点ほど異なる点があります。

一つ目は配布先を複数にしている点。Zaim では何度か、App Store にアップロードしたバイナリが壊れしまい動かなくなるという問題に遭遇しました。その発生確率を少しでも減らすために、App Store にアップロードしたバイナリを再度 Ad-hoc 版で署名し直し、社内用配布ツールである DeployGate にもアップロードし、動作確認するようにしています。

App Store 用ビルドも Ad-hoc 版と同様、disable_automatic_code_signing してから App Store 用のファイルを利用するように変更します。

もう一つは公開用のメタデータなどの準備と配信です。これには fastlane deliver を使っています。

fastlane deliver を使うと、スクリーンショットやアプリの説明といったメタデータを Git リポジトリで管理できるようになります。

まとめると、App Store 配信の流れとしては、

1. App Store 用のプロビジョニングプロファイルなどを取得する
2. disable_automatic_code_signing してビルドする
3. fastlane deliver でアップロードする
4. Ad-hoc 用のプロビジョニングプロファイルなどを取得する
5. resign で Ad-hoc 用に署名を書き換える
6. DeployGate に配信する

ということを実行しています。App Store 用に作った IPA をDeployGate で配信するには、IPA に署名しているプロビジョニングプロファイルを変更する必要があります。署名の書き換えは、resign を使うと簡単です。

resign(
    signing_identity: "iPhone Distribution)",
    provisioning_profile: ENV["sigh_bundle_identifier_adhoc_profile-path"]
)

こちらでも、match が環境変数にセットしたプロビジョニングプロファイルを使うよう設定を変更しています。

以上のようなコードで、Xcode Automatically Manage Signing と fastlane match の共存できるようになり、泥臭い・ややこしい・意味が分かりにくいという三重苦だったプロビジョニングプロファイルと証明書の管理をシンプルにしました。

なお、デバイスの登録や TestFlight の扱い、プロビジョニングプロファイルなどの更新については整備中で、これから簡略化できるよう改善していこうと考えています。

余談:11 月に Bitrise が東京に来るそうです

Zaim では効率化が大好きなエンジニアを募集しています。