怖くないiOSの証明書

この記事は [freee Engineers Advent Calendar](http://qiita.com/advent-calendar/2016/freee) の7日目です。

こんにちは、freeeでエンジニアをしている @bl-lia です。普段はモバイルアプリをメインに開発しています。
今日は、みんな大好きiOSの証明書まわりの話をしようと思います。

# なぜ今になって証明書の話？
iOSの証明書まわりは面倒くさいというのは、あるあるネタとして通るくらいiOS開発をちょっとでもかじったことのある人なら分かってくれるネタだと思います。
ただ、世の中にはこの証明書まわりを解説してくれている記事が山ほどあるのになぜまたこの証明書の話を取り扱うのか。
それは **私が理解できなかったから** です。

# なぜ理解できなかった？
単純に私の理解力が足らないというのもあるのですが、それ以外にもこんなことが私の理解を邪魔します。

- 「既にリリースしているアプリの証明書がなんかおかしくなってるから直したい」みたいな時、手順ベースで一から解説している記事を参考にできたとしても、あの複雑な仕組みを1年後とかに覚えている自身がない。どこの手順から始めればいいのか分からなかったり、そもそも手元の環境と記事が微妙に違ってたりする。
- 記事は個人開発向けに書かれてるけど、チーム開発とはどこの手順が違うのかよく分からない
- Apple Developerのページ上でProvisioning ProfileがInvalidになってるけど、あんまり理解せずに触ると余計状況が悪化しそうで、チームにも迷惑かけるし迂闊に触れない
- Xcode上でProvisioning Profileがエラーになってるけど、あんまり理解せずｎ (ry

なので、こんな私でも理解できるように、 **最低限のことをポイントを抑えて理解する** ことにしました。
今回は、私がどんな風にポイントを抑えたら理解できたのか、ということを紹介したいと思います。

ちなみに、今回の話はチーム開発を行うことが前提で紹介しますが、個人開発でもだいたい同じような理解でいけるかなと思います。
また、プッシュ通知まわりの証明書の話は今回割愛します。

# 証明書まわりで必要なファイル
証明書まわりは登場するファイルの種類が多いので「あれ、このファイルどこで必要になるんだっけ...」みたいな事態になりがちです。
なので、どういう種類のファイルが存在するのかと、それがどういう役割なのかを抑えます。

## CSRファイル (certSigningRequestファイル)
ローカルマシン上で作成する、個人を特定するキーとなるファイルです。
後で説明するcerファイルをダウンロードしてローカルマシンに取り込むと、ローカルマシンのKeychain Access上でcertificateとprivate keyが紐付きます。
これでローカルマシン内で個人が特定できるようになります。
このファイルはApple Developerからダウンロードできないので、どこかに保存しておく必要があります。
このファイルをなくした場合、Certificateは作り直しになりますし、Provisioning Profileは再度設定しなおす必要があります。

## 証明書ファイル (cerファイル)
開発者個人を特定するための証明書、またはAd Hoc用やリリース用の証明書です。[iOS Certificates](https://developer.apple.com/account/ios/certificate/)で一覧を見ることが出来ます。
CSRファイルの所でも説明しましたが、cerファイルをダウンロードして取り込むことで、ローカルマシン内のKeychain Access上でcertificateとprivate keyが紐付きます。
「cerファイルを取り込んだけれども、Keychain Access上でcertificateしか表示されない」という場合、CSRファイルを作ったローカルマシンとcerファイルを取り込んだマシンが一致してない可能性があります。

## p12ファイル
Keychain Access上でcertificateやprivate keyをエクスポートすると作成されるファイルです。
チーム開発の場合だと、リリース用に作成した証明書を他のマシンに移行する時とかに使用します。「移行する」と書きましたが、エクスポートして消えるものではないので、移行元のマシンでも今まで通り使えます。
リリース用の証明書がないとリリース向けにアプリをビルドできないので、 **どのマシンにリリース用の証明書が入っているか** というのはチーム内でちゃんと認識を合わせておいた方がいいと思います。
もしビルドしたいマシンに証明書がない場合は、このp12ファイルを使用してやりとりします。

よくあるのが「最初一人で開発していて、その後人数が増えて自動化したのでリリースを共有マシンからやりたい」とか「最初低スペックのマシンで開発していたけど、高スペックのマシンに買い換えたのでそっちでリリース用ビルドもしたい」とか、こういう時に必要になってきます。
あとは、プッシュ通知をFirebaseなどの外部サービス経由でやりたい場合にも使ったりします。

# Provisioning Profile
証明書まわりが理解できたら、次はProvisioning Profileまわりを理解していきます。
Provisioning ProfileまわりはだいたいApple DeveloperのCertificates, Identifiers & Profilesの画面でなんとかなります。
登場する要素としては

- Certificates -> 上で作った証明書ファイル
- Identifiers -> アプリのidentifier
- Devices -> 開発機として登録されている端末
- Provisioning Profiles -> 上の3つを紐付けたプロファイル

こんな感じなのですが、環境ごと(Debug、Releaseなど)に条件が異なってくるのでそれぞれの条件で確認するチェックポイントをまとめました。
エラーになってるときは、だいたい以下のどれかが設定漏れになってたりするケースが多いです。

## Debug
- Apple DeveloperのCertificatesのDevelopmentに自分がいる
- そのCertificatesをダウンロードして、ビルドしたいマシン内でcertとprivate keyが紐付いている
- Apple DeveloperのIdentifiersのApp IDsにアプリのBundle IDがある
- 実機でデバッグするときは、Devicesに対象の実機が登録されている
- Provisioning ProfiilesのDevelopmentに、 上のCertificatesとApp IDとDevicesが全て登録されている
- Provisioning Profileがビルドしたいマシン上にダウンロードされている
- ダウンロードするには、Apple Developerからダウンロードするか、XcodeのAccountsからダウンロード

## Staging (AdHoc)
- Apple DeveloperのCertificatesのProductionに チーム用のCertificateがいる
- そのCertificatesをダウンロードして、ビルドしたいマシン内でcertとprivate keyが紐付いている
- 紐付いてない場合、紐付いてるマシンからprivate keyをエクスポートするか、certSigningRequestファイルを新規に作って、Certificatesも新規に作り直す
- Devicesに対象の実機が登録されている
- Provisioning ProfilesのDistributionのAdHoc用のやつに、 上のCertificatesとApp IDとDevicesが全て登録されている
- Provisioning Profileがビルドしたいマシン上にダウンロードされている
- ダウンロードするには、Apple Developerからダウンロードするか、XcodeのAccountsからダウンロード

## Production (Release)
- Apple DeveloperのCertificatesのProductionに チーム用のCertificateがいる
- そのCertificatesをダウンロードして、ビルドしたいマシン内でcertとprivate keyが紐付いている
- 紐付いてない場合、紐付いてるマシンからprivate keyをエクスポートするか、certSigningRequestファイルを新規に作って、Certificatesも新規に作り直す
- Provisioning ProfilesのDistributionのRelease用のやつに、 上のCertificatesとApp IDが全て登録されている
- Provisioning Profileがビルドしたいマシン上にダウンロードされている
- ダウンロードするには、Apple Developerからダウンロードするか、XcodeのAccountsからダウンロード

# 故障かな？と思ったら (Troubleshooting)
ここまで理解したけれども、やっぱりビルドできないときはビルドできないもんです。
そんなときでも慌てずに、もう一度上の証明書まわりやProvisioning Profileのチェックポイントを見直すか、または以下のようなケースに遭遇している場合はそれぞれの確認ポイントをもう一度見てみましょう。

## なんかProvisioning ProfileがInvalidとかなってる
Provisioning ProfileのEditを押して中身を確認しましょう。
だいたい、App IDが紐付いてないとか、必要なCertificatesが紐付いてないとかそんな場合が多いです。

## なんか上手くいかないのでCertificatesを一旦Revokeして作り直した
Certificateに元々紐付いていたProvisioning Profileを確認しましょう。
RevokeしたのがDistribution用のCertificateだったら、おそらくProvisioning ProfileがInvalidになってると思います。その場合は、リリース用のProvisioning ProfileのEditからCertificateを選び直しましょう。
RevokeしたのがDevelopment用のCertificateだったら、自分のCertificateが紐付いてなくてXcode上で怒られてるはずです。この場合は、Develop用のProvisioning ProfileのEditから選び直しましょう。

## Provisioning Profileを更新したけど、Xcode上で怒られてる
Apple Developer上で更新したけれども、それをビルドしたいマシンに反映できてないケースです。
その場合は、ビルドしたいマシンにあるProvisioning Profileを最新にしましょう。
XcodeのAccountsから取り込むのが楽です。
ただ、XcodeのAccountsはProvisioning Profile更新直後だと取得できない時もあったりするので、その場合はApple Developerからダウンロードするのが確実です。

## Fix Issue押したらとりあえず動いたけど、Provisioning ProfileみたらInvalidとかなってる
Provisioning ProfileのEditを押して、なにが紐付いていないのか確認しましょう。
Fix Issueは基本チームで開発してることを一切考慮せずにIssueをFixしようとするので、だいたいIssueがFixしないです。つらい。

## CertificateやProvisioning Profileの期限が切れた
新しく作り直しましょう
作り直した後は、Certificate、App ID、DeviceがちゃんとProvisioning Profileに紐付いているか確認しましょう。

# さいごに
「いざ実機デバッグしようとしたらできなくて余計な時間を使った」とか「いざリリースしようとしたらビルドできなくて慌てた」とか、そんな非生産的なことは二度としたくないので、自分も忘れそうになったらこの記事をまた見返したいと思います。
また、[freeeではモバイルエンジニアをはじめ絶賛エンジニア募集中](https://jobs.freee.co.jp/)なので、気になる方は是非遊びに来てください！

さて明日は、エンジニア朝会で華麗に司会をこなす男こと @takatm です。こうご期待！