[iOS]macOSのVM環境で特定のstoryboard, xibファイルのコンパイルに時間がかかる問題

## 概要

iOSアプリのアーカイブ自動化の目的のためモバイル用のCIサービスである[Bitrise](https://www.bitrise.io/)を利用してみました。

アプリ、ワークフローの作成を済ませビルドを行ってみると特定のstoryboard, xibファイルのコンパイルに17分程度の時間を要することが分かりました。
ローカルマシンのMacではそういった問題は発生せず、該当ファイルは1秒もかからずにコンパイルが完了していました。

特定のstoryboard, xibファイルの共通箇所を見つけて修正した所、上記問題が解決したのでその原因と対応をまとめたいと思います。

## 環境

- ローカルマシンのMac
    - macOS High Sierra 10.13.6
    - Xcode 9.4.1
- [BitriseのVM環境](https://github.com/bitrise-io/bitrise.io/blob/2232a84/system_reports/osx-xcode-9.4.x.log) のMac
    - macOS High Sierra 10.13.5
    - Xcode 9.4.1

## 調査したこと

特定のstoryboard, xibファイルを調査した所、Text属性が`Attributed`となっており、フォントとしては`Hiragino Sans CNS`が設定されているUILabelが共通して存在している事が分かりました。
この内容を元にググると似たような事象がでてきました。

- [fastlane+bitrise+deploygateでCI環境をつくる](https://tech.camobile.com/entry/2018/04/20/120000)
- [How to use custom fonts in attributed text in labels in Storyboard?](https://discuss.bitrise.io/t/how-to-use-custom-fonts-in-attributed-text-in-labels-in-storyboard/1807)

どうやらBitriseでビルドする際に存在しないカスタムフォントを利用していると固まる事象が起きるそうです。
それを解決するには該当のカスタムフォントファイルをアーカイブ前に実行マシンにインストールすればよいとの事です。


ここでふと`あれ、そもそもローカルマシンで【Hiragino Sans CNS】なんていうフォントインストールした記憶ないけど…`という疑問が沸いて来ました。

そもそもフォントファイルがどこに格納されているか調べてみると、[こちら](https://discussionsjapan.apple.com/message/101071484#message101071484)に記載がある通り以下のようになるようです。

- /System/Library/Fonts
    - 削除や使用停止に出来ない
- /Library/Fonts
    - 削除や使用停止に出来る
- /System/Library/Assets/com_apple_MobileAsset_Font4
    - 必要に応じてダウンロードや削除、使用停止に出来る
    - このパスはmacOS High Sierraの場合となります
    - macOS Mojave だと `/System/Library/Assets/com_apple_MobileAsset_Font5` になるようです


`macOS High Sierra`のデフォルトインストールフォントの一覧が[Appleのサポートページ](https://support.apple.com/en-ng/HT207962)に記載されています。
こちらのページを覗いてみると、`Hiragino Sans CNS`はダウンロードして使えるフォント一覧に含まれていました。
つまり、`/System/Library/Assets/com_apple_MobileAsset_Font4`配下にあることとなります。

以下のコマンドをローカルマシンで叩いてみると確かに該当のフォントファイルが存在していることが分かります。

```bash
$ cd /System/Library/Assets/com_apple_MobileAsset_Font4
$ find . -name "Hiragino*"
./f49eecf252fb0fa3485147173cadc8dfe5f10d74.asset/AssetData/Hiragino_Sans_CNS.ttc
```

同様に`/System/Library/Assets/com_apple_MobileAsset_Font4`配下には様々なカスタムフォントファイルが存在していることが分かりました。
自分でこんなにカスタムフォントをインストールした記憶はやはりないので、もうちょっと調べてみると[こちら](http://dslabo.blog4.fc2.com/blog-entry-2375.html)のページに以下の記載がありました。

>実は実機と仮想環境との2台で確認したんですが、仮想環境のほうはOSインストール直後段階ではAssetsにフォントがインストールされなかった

この内容から推測すると恐らくローカルマシンのMacでは出荷時点で既にダウンロード可能なフォントもインストール済みなのかもしれません。
<font color="Crimson">※実際に出荷直後、または、初期化直後のマシンの中を確認した訳ではないので不正確な情報かもしれません。</font>

一方、仮想環境ではインストールされていなかったという記述があったので、BitriseのワークフローにScriptステップを追加し、以下のコマンドを叩いてみました。

```bash
$ ls -l /System/Library/Assets/com_apple_MobileAsset_Font4
total 272

-rw-r--r--  1 root  wheel  136411 Oct 31 03:43 com_apple_MobileAsset_Font4.xml
$ ls -l /System/Library/Fonts
total 884056
-rw-r--r--  1 root  wheel     266008 Jul 31  2017 Apple Braille Outline 6 Dot.ttf
︙
$ ls -l /System/Library/Fonts | wc -l
115

$ ls -l /Library/Fonts
total 251376
-rw-r--r--  1 root  wheel    131264 Aug  8  2017 Al Nile.ttc
︙
$ ls -l /Library/Fonts | wc -l
181
```

結果としてやはり`/System/Library/Assets/com_apple_MobileAsset_Font4`配下に`Hiragino Sans CNS`フォントは存在していませんでした。
他のシステムフォントはローカルマシンと同様の結果であることも確認できました。

### 追加検証

`Hiragino Sans CNS`は削除可能なフォントであるので、ローカルマシン上から削除して同様にビルドしたらどうなるのかを検証してみました。
※該当フォントの削除はアプリケーション【Font Book】から行うことができます。

すると、同様に該当のstoryboard, xibファイルがコンパイルされる際に以下のようなポップアップが表示されました。

<img width="416" alt="ダウンロードポップアップ" src="https://qiita-image-store.s3.amazonaws.com/0/2871/aba838f0-7efb-f08a-a24b-5ed830b4add2.png">


このポップアップを無視して放置していると、Bitrise上でのアーカイブ処理と同様に17分程度経過すると、該当ファイルのコンパイルは終了することがわかりました。

また、`Hiragino Sans CNS`が削除された状態で該当のstoryboard, xibファイルをInterface Builderで表示してみると、以下のようなモーダルが表示されます。

<img width="435" alt="InterfaceBuilderモーダル" src="https://qiita-image-store.s3.amazonaws.com/0/2871/6ee7d44c-4f68-c075-cdd6-1d7b5801be9b.png">


>Font “HiraginoSansCNS-W3” does not exist on this system, substituting the system font instead. Saving the document will lose the original font reference.

ここの文章に着目すると、該当のフォントが存在しない場合には代わりにシステムフォントが利用されることが分かりました。

## 今回の対応・まとめ

今回はそもそもフォント`Hiragino Sans CNS`を利用する想定では無かったので、こちらのフォントを本来のフォントに変更して対応しました。
該当ファイルの作成時点で、変なフォントを設定していた事を反省しなければなりません…

仮に上記フォントを利用する場合、Bitrise側でVM環境にフォントをインストールするステップを追加したとしてもiOSのフォント一覧にも含まれていないので、システムフォントに切り替わって表示されてしまうかと思います。
本当にこのフォントを利用したい場合には、iOSアプリのリソースとして追加しておく必要があるかと思います。