xcodebuildの-exportOptionsPlist の設定項目を一通り調べてみました

# はじめに

iOS アプリの ipa パッケージをコマンドで作成する際には `xcodebuild` の `-exportOptionsPlist` オプションに plist ファイルの指定が必要です。

この plist には様々な設定を記述するのですがそれぞれに意味がイマイチ理解しきれていなかったため、あらためて調べてみました。`xcodebuild -h` で表示される説明を一通り確認し簡単な和訳と説明を行っています。

使用した Xcode のバージョンは以下です。

```
$ xcodebuild -version
Xcode 11.0
Build version 11M362v
```

ちなみに、fastlane では plist の設定項目は `build_ios_app` アクションの `export_options` パラメータの値として指定できます。

# オプション一覧
## compileBitcode

> compileBitcode : Bool
> For non-App Store exports, should Xcode re-compile the app from bitcode? Defaults to YES.

iOSアプリはコンパイラとして [LLVM](https://llvm.org/) を利用しますが、 Bitcode は LLVM が生成する中間コードのことです。Bitcode を App Store にアップロードするアプリに含めておくと、再申請せずとも Apple 側でアプリを再コンパイルできるため将来的に最適化できる可能性があるとのことです。

`compileBitcode` フラグを `true` に設定すると パッケージの作成時に Bitcode から再コンパイルされます。App Store 向けの ipa 作成時はここでの設定によらず再コンパイルされません。

再コンパイルはアプリの規模によっては数分かかってしまうこともあるため、基本的に `false` がよいと思います。

参考

- https://developer.apple.com/videos/play/wwdc2015/404/
- https://help.apple.com/xcode/mac/current/#/devbbdc5ce4f

## destination

> destination : String
>
> Determines whether the app is exported locally or uploaded to Apple. Options are export or upload. The available options vary based on the selected distribution method. Defaults to export.

App Store 向けの パッケージ 作成時、`upload` に設定しておくと、同時に TestFlight へのアップロードまで実行します。アカウントは Xcode の Preference で設定した内容が利用されます。デフォルトは `export` で、アーカイブをローカルに作成します。

## embedOnDemandResourcesAssetPacksInBundle

> embedOnDemandResourcesAssetPacksInBundle : Bool
>
> For non-App Store exports, if the app uses On Demand Resources and this is YES, asset packs are embedded in the app bundle so that the app can be tested without a server to host asset packs. Defaults to YES unless onDemandResourcesAssetPacksBaseURL is specified.

[On-Demand Resources](https://developer.apple.com/library/archive/documentation/FileManagement/Conceptual/On_Demand_Resources_Guide/index.html)利用時、`true` に設定するとパッケージ内にリソースが埋め込みまれ、On-Deman Resources 配信用のサーバーが不要になります。デフォルトは `true` です。

## generateAppStoreInformation

> generateAppStoreInformation : Bool
>
> For App Store exports, should Xcode generate App Store Information for uploading with iTMSTransporter? Defaults to NO.

App Stoer 向けの パッケージ作成時、`true` に設定すると iTMSTransporter でアップロードに利用するための `AppStoreInfo.plist` を生成します。このファイルは Linux もしくは Windows で iTMSTransporter を実行する際に必要になります。

## iCloudContainerEnvironment

> iCloudContainerEnvironment : String
>
> If the app is using CloudKit, this configures the "com.apple.developer.icloud-container-environment" entitlement. Available options vary depending on the type of provisioning profile used, but may include: Development and Production.

アプリが CloudKit を利用している場合、iCloud コンテナの環境（ Development or Producetion ）を指定できます。

## installerSigningCertificate

> installerSigningCertificate : String
>
> For manual signing only. Provide a certificate name, SHA-1 hash, or automatic selector to use for signing. Automatic selectors allow Xcode to pick the newest installed certificate of a particular type. The available automatic selectors are "Mac Installer Distribution" and "Developer ID Installer". Defaults to an automatic certificate selector matching the current distribution method.

macOS アプリ向けの設定で、manual signing 設定の場合に使用されるます。macOS アプリではアプリ自体の証明書と、インストーラー用の証明書の二種類が必要なようで、こちらはインストーラー向けの設定になっています。証明書の名前かSHA-1ハッシュ、もしくは自動セレクタを指定できます。自動セレクタを指定すると Xcode はそのタイプの最新の証明書を選択します。指定可能な自動セレクタは `Mac Installer Distribution` と `Developer ID Installer` です。デフォルトは `method` にマッチする自動セレクタになります。

## manifest : Dictionary

> manifest : Dictionary
>
> For non-App Store exports, users can download your app over the web by opening your distribution manifest file in a web browser. To generate a distribution manifest, the value of this key should be a dictionary with three sub-keys: appURL, displayImageURL, fullSizeImageURL. The additional sub-key assetPackManifestURL is required when using on-demand resources.

App Store 向け以外で export したパッケージを web 経由で端末にインストールするには、manifest ファイルをブラウザで開きます。manifest に、パッケージファイルやアイコン画像の URL、アプリ名など記載します。このオプションでのその plist ファイルを生成できます。`appURL`、 `displayImageURL`、`fullSizeImageURL` キーを指定でき、また追加で、on-demand リソース用の `assetPackManifestURL` を指定できます。

## method

> method : String
>
> Describes how Xcode should export the archive. Available options: app-store, validation, package, ad-hoc, enterprise, development, developer-id, and mac-application. The list of options varies based on the type of archive. Defaults to development.

アーカイブを export する方法を指定します。 有効な値は `app-store`, `validation`, `package`, `ad-hoc`, `enterprise`, `development`, `developer-id`, and `mac-application` で、アーカイブのタイプによって指定可能な値は変わります。

Key | 意味
:-: | :-:
app-store | App Store にアップロードする用
validation | パッケージの内容に問題がないか。App Store にアップロードして検証される
package | MacOS用？
ad-hoc | AdHoc 配布用
enterprise | In-house 配布（組織内配布）
development | 開発用
developer-id | MacOS用？
mac-application | MacOS用？


## onDemandResourcesAssetPacksBaseURL

> onDemandResourcesAssetPacksBaseURL : String
>
> For non-App Store exports, if the app uses On Demand Resources and embedOnDemandResourcesAssetPacksInBundle isn't YES, this should be a base URL specifying where asset packs are going to be hosted. This configures the app to download asset packs from the specified URL.

On Demand Resources をダウンロードする URL を指定します。App Stoer 配布以外かつ `embedOnDemandResourcesAssetPacksInBundle` が `false` の場合このオプションを指定する必要があります。

## provisioningProfiles

> provisioningProfiles : Dictionary
>
> For manual signing only. Specify the provisioning profile to use for each executable in your app. Keys in this dictionary are the bundle identifiers of executables; values are the provisioning profile name or UUID to use.

manual signing の場合、アプリ中の各実行ファイルが使用するプロビニングプロファイルを指定します。値はプロファイルの名前もしくは UUID を使用します。

## signingCertificate

> signingCertificate : String
>
> For manual signing only. Provide a certificate name, SHA-1 hash, or automatic selector to use for signing. Automatic selectors allow Xcode to pick the newest installed certificate of a particular type. The available automatic selectors are "Mac App Distribution", "iOS Distribution", "iOS Developer", "Developer ID Application", "Apple Distribution", "Mac Developer", and "Apple Development". Defaults to an automatic certificate selector matching the current distribution method.

manual signing の場合、証明書の名前、SHA-1ハッシュ、もしくは、自動セレクタのいずれかを指定します。自動セレクタを指定すると Xcode がインストールされた最新の証明書を適宜選択します。　

指定可能な値は `Mac App Distribution`、 `iOS Distribution`、 `iOS Developer`、 `Developer ID Application`、 `Apple Distribution`、 `Mac Developer`、 and `Apple Development` です。デフォルトでは `method` の設定にあったものが選択されます。

Distribution と名前が付いているものは App Store への申請用や、AdHoc配布に使うものです。

`Apple Distribution` と `Apple Development` は、Xcode 11 から追加された証明書で、iOS や Mac に関わらず使用できます。

## signingStyle

> signingStyle : String
>
> The signing style to use when re-signing the app for distribution. Options are manual or automatic. Apps that were automatically signed when archived can be signed manually or automatically during distribution, and default to automatic. Apps that were manually signed when archived must be manually signed during distribtion, so the value of signingStyle is ignored.

配布用のアプリの再署名に使用する署名のスタイルを指定します。`manual` もしくは `automatic` が指定可能です。

アーカイブの際に自動署名で作成されたアプリは、`manual` でも `automatic` でも署名できます。デフォルトは`automatic` です。アーカイブの際に manually signed で署名されたアプリは配布用でも manually signed でなければなりません。そのため、`signingStyle` の値は無視されます。

## stripSwiftSymbols

> stripSwiftSymbols : Bool
>
> Should symbols be stripped from Swift libraries in your IPA? Defaults to YES.

`true` に設定すると IPA ファイル内の Swift ライブラリからシンボルを切り捨て、IPAファイルのサイズを削減します。デフォルトは `true` です。

## teamID

> teamID : String
>
> The Developer Portal team to use for this export. Defaults to the team used to build the archive.

export に使用する Developer Portal のチームを指定します。デフォルトはアーカイブ時に使用したチームになります。

## thinning

> thinning : String
>
> For non-App Store exports, should Xcode thin the package for one or more device variants? Available options: <none> (Xcode produces a non-thinned universal app), <thin-for-all-variants> (Xcode produces a universal app and all available thinned variants), or a model identifier for a specific device (e.g. "iPhone7,1"). Defaults to <none>.

App Store 向けでない export 向けの設定で、パッケージを特定のデバイス用に Thinning するかどうかを設定します。`<none>` を指定すると Xcode は Thinning を行わず universal app を生成します。デフォルトは `<none>` です。`<thin-for-all-variants>` を指定すると、Xcode は universal app と、Thinning が有効なすべての対象に対対象向けのパッケージを生成します。その他には、`iPhone7,1` といった各種デバイスの識別子を指定できます。


試しに `<thin-for-all-variants>` を指定すると、Apps ディレクトリの中に以下の用に ipa ファイルが複数生成されました。myapp.ipa は universal app でサイズは 10MB、その他は 3MB ほどだったので、かなりサイズが削減できていますね。

```
myapp-6E31FB2D-E589-4593-802F-5D2AFFC861B9.ipa  myapp-A107265C-8696-4B36-AC2B-A4A5084A1EB0.ipa
myapp-6FBAF36E-2DFE-4367-B168-9580849C778D.ipa  myapp-B31D5E02-F3B5-42E1-A728-B6A318D7C6F0.ipa
myapp-9A297506-7DD4-49D6-85A7-D772B6BF5AC4.ipa  myapp-B55C5B6A-275D-42FD-A9F7-C22302D08286.ipa
myapp-77DCAAA5-11CE-48B1-841D-97F69983F0C6.ipa  myapp-BEF1052D-E469-4688-97BF-66CCF0522502.ipa
myapp-175FAC87-BAD4-47AA-A7B2-D97F37A2C784.ipa  myapp-E9F18918-4D58-4B70-8937-19DE6DCD0806.ipa
myapp-199FE0F4-F5C6-4551-BC1E-9831D20DFF40.ipa  myapp-E38340C4-CEDA-49B2-ABC7-F2852868ACD3.ipa
myapp-268FD55C-AB62-446B-B3A9-5236C9E864FE.ipa  myapp-F024868D-2A76-4CD5-A0A9-6AF8D7A3BB2A.ipa
myapp-604EABFF-533E-4EFD-B3A6-FB8E8837B0DB.ipa  myapp-F9DFFC7E-EDD9-4509-B937-A500E53A88B2.ipa
myapp-797903DB-A9F2-4F08-8462-64A082AB1C5F.ipa  myapp.ipa
```

## uploadBitcode

> uploadBitcode : Bool
>
> For App Store exports, should the package include bitcode? Defaults to YES.

App Store 向けの export の設定で、bitcode をパッケージに含めるかどうかを設定します。デフォルトは `true` です。

bitcode をパッケージに含めておくと、再申請せずとも Apple 側でアプリを再コンパイルできるため将来的に最適化できる可能性があるとのことなのですが、定期的にアプリをアップデートしているアプリでは、bitcode がどれほどの意味を持つのかはよくわかっていません。

## uploadSymbols

> uploadSymbols : Bool
>
> For App Store exports, should the package include symbols? Defaults to YES.

App Store 向けの export の設定で、シンボル情報をパッケージに含めるかどうかをせて治します。デフォルトは `true` です。シンボルをパッケージに含めておくと、利用者のクラッシュログを Xcode 上でシンボルが有効な状態で閲覧可能になります。



# 感想

一通り見てみると、知らなかったオプションがあり勉強になりました。特に、`destination` オプションに `upload` を指定すると、TestFlight にアップロードする機能まであったのには驚きました（使う機会はなさそうですが……）。