ProvisioningProfileって何なの？iOSアプリ開発における役割について

# ProvisioningProfileとは
ProvisioningProfileとは、iOSアプリのコード署名に必要なファイルです。
Xcodeはアプリバイナリのビルド時にProvisioningProfileを使用して、以下の情報をアプリバイナリに格納しています。
- アプリ発行元の証明書(公開鍵)
- アプリID
- (開発用プロファイルのみ)開発実機端末のUUID

## ProvisioningProfileの目的
ProvisioningProfileが果たす主な役割は、以下の二つです。
- アプリバイナリの開発元が本物であることを証明する。
- (開発版アプリのみ)開発者が指定した端末にのみアプリをインストールできるようにする。

これらの目的を達成するため、開発元の証明書やデバイスの情報をProvisioningProfileにパッケージ化し、アプリに組み込みます[^1]。
[^1]: この目的を果たすためにCodeSigningの仕組みはつくられました。筆者個人としては、もっとよい設計があるのではないかと考えていますが、この手続きと向きあわない限りiOSアプリをリリースすることはできません。

「iOSアプリにおけるProvisioningProfileの役割と、開発者がどのように対応するのか」に焦点を当てた概略図を、以下に示します。

```plantuml
@startuml
title ProvisioningProfileによるコード署名の手続き
footer: author: rodentia6
package "Apple Developerコンソール" <<rectangle>> #line.dashed{
    note as note1
        ①Web上で
        ProvisioningProfileの生成に必要な各項目を入力する。
    end note
    file "Provisioning\nProfile" as propro {
    }
    card "証明書(公開鍵)" as cert {
    }
    card "アプリID" as identifier{
    }
    card "開発用iOS端末ID" as device {
    }
    card "Profile区分\n(リリース/開発)" as pro{
    }
    cert --> propro 
    identifier --> propro
    device --> propro
    pro --> propro
}
package "MacOS" <<rectangle>> #line.dashed{
    card "秘密鍵" as private {
    }
    package "Xcode" as xcode <<rectangle>> #line.dashed {
        file "アプリコード" as appcode{
        }
        file "Provisioning\nProfile" as propro2 #88eeee {
        }
        circle "." as build #000000
        node "iOSシミュレーター" as simu {
        }
        appcode --> build
        appcode -right-> simu 
    }
    file "署名済みアプリ\n(開発用ビルド)" as shomei1 {
    }
    file "署名済みアプリ\n(リリース用ビルド)" as shomei2 {
    }
    
}
node "開発用iOS端末" as iosdevice{
}
cloud "AppStore" as appstore {
}
note right of build : ③アプリのビルド時に秘密鍵を用いて\nProvisioningProfileを署名する。\n\n署名するProvisioningProfileは\n開発ビルド/リリースビルドで使い分けなくてはならない。
note top of simu : ちなみに、iOSシミュレーターに\nアプリをインストールする場合は\nコード署名はしない。
cert .. private
propro --> propro2
note on link : ②生成されたProvisioningProfileを\nローカルにコピーする。
private --> build
propro2 --> build
build --> shomei1
build --> shomei2
shomei1 --> iosdevice : インストール
shomei2 --> appstore : アップロード
@enduml
```

# ProvisioningProfileの構成要素
ProvisioningProfileは `Certificate` x `Identifier` x `Device` x `Profile区分` の組み合わせによって定義されています。  

以降の節はhttps://developer.apple.com/account/resources (要ログイン) を眺めながら読んでもらうことを想定しています。

## Certificates - 証明書
Certificate（証明書と訳される）とは、アプリの発行元を証明するものです。  
Certificateは開発者個人であったり、機関であったりします。  

用途によって以下の区分があります。  
- Distribution(発行元。AppStoreへのリリース等配布用)
- Development(開発者。開発用)  

システム的には、Certificate≒公開鍵であり、発行時の秘密鍵とセットで持つ必要があります。

Development区分のCertificateは概念の上では開発者個人に紐付けられているようですが、  
メンバー毎に異なるCertificateを定義し直す運用は管理が複雑になる為、チームで1つの秘密鍵を共有したほうが開発効率がよいです。  

また、Certificateには有効期限があり、発行から1年後に失効するようになっているため、定期的な再発行とキーチェーンへの再インストールが必要です。   
ProvisioningProfileはCertificateによって構成されているのでこちらも同様にXcodeへの定期的な再インストールが必要です。


## Identifiers - アプリID
AppStore内で一意となるアプリIDのこと。  
たとえばブラウザのSafariであれば `com.apple.mobilesafari` 

## Devices - 実機端末
デバイスIDの情報をProvisioningProfileに載せることによって、開発用ビルドのアプリが開発者の意図した端末でしか動作しないように制限しています。  
DeviceはDevelopment区分のプロファイルでのみ設定される項目です。

## Profilesとは
プロビジョニングプロファイルのこと。  
前述したとおり、プロビジョニングプロファイルは `Certificate` x `Identifier` x `Device` x `Profile区分` の組み合わせによって定義されています。  
用途によって以下のProvisioningProfile区分があります。  
- AppStore(AppStoreへのリリース用)
- Development(開発用)
- AdHoc(アドホック)

プロビジョニングプロファイルはAppleサーバー上で生成されるので、開発機のローカルに落とした上でXcodeにインストールし、アプリのビルド時にプロビジョニングファイルを使用するという以降の流れに続きます。