ipaファイルのサイズが大きい…色々試してみた！

# はじめに
初めてアプリを作りました！が、テーマの件で戸惑ったので備忘録として挙げておきます。
以下の環境で開発を行い、いざtestFlightにあげるぞ！というとこでした。
環境：Xcode9.3
言語：Swift4.1

# ipaファイルを作ったらファイルサイズが100MB超え。。。
とっても簡素なアプリなのですが、何故かファイルサイズが巨大なことに。。
![スクリーンショット 2018-04-19 19.40.51.png](https://qiita-image-store.s3.amazonaws.com/0/251327/88c409d8-3b2c-2d8b-55cb-bf425e821b33.png)

# 調べてみた
まずはどのファイルが原因なのか調査してみました！

1. Archiveしたファイルを開く
 Window -> Organizer　で該当ファイルのあるフォルダを開く
 ![スクリーンショット 2018-04-20 10.57.51.png](https://qiita-image-store.s3.amazonaws.com/0/251327/a11641fc-30e4-3f25-2c1c-3e71a731ca6b.png)

1. ファイルの中を見る
![スクリーンショット 2018-04-20 11.02.00.png](https://qiita-image-store.s3.amazonaws.com/0/251327/9445467a-c4ac-8e22-e5ee-2aba395c1a63.png)

1. .xarchiveの中はこんな感じ。
明らかにApplicationsの中身が大きい。。これもパッケージの内容を見てみる！![スクリーンショット 2018-04-20 11.05.21.png](https://qiita-image-store.s3.amazonaws.com/0/251327/1ced7fae-f9d9-fb85-f2f0-fed721afe707.png)

1. なんかframeworkがとても大きいぞ。。
実行ファイルが6MB程度なのにframeworkだけで113MB。。
しかも囲っている**libswiftCore.dylib**と**libswiftFoundation.dylib**がとても大きい！これらは一体何なのか？？
![スクリーンショット 2018-04-23 19.35.37.png](https://qiita-image-store.s3.amazonaws.com/0/251327/a1da1936-6ce4-ba28-9a60-bb36241f09c2.png)

# 何でframeworkがここまで大きい？
なかなか調べても答えが見つからないため、[質問してみました！](https://ja.stackoverflow.com/questions/43494/ipa%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E5%86%85%E3%81%AEframeworks%E3%81%AE%E3%82%B5%E3%82%A4%E3%82%BA%E3%81%8C%E8%86%A8%E3%82%8C%E4%B8%8A%E3%81%8C%E3%81%A3%E3%81%A6%E3%81%84%E3%82%8B%E3%81%AE%E3%81%AF%E4%BD%95%E6%95%85)

## 答え
**Swiftを使っているから。**
そもそもこれらはSwiftを動かすための必須ライブラリであり、Objective-Cで書かない限りは必ず内包されるものなのだそうです。(→参考: [Swift と Objective-C どっち選ぶ？](http://blog.sorausagi.org/2017/10/swift-objective-c.html))
年々そのサイズが膨れ上がっているのはXcodeのバージョンが上がって機能が追加されているからなのでした。。
またiTunesConnectにアップロードされる際には各デバイスが必要なライブラリのみを取得するので、100MB等巨大なサイズになることはまず無いそうです。ひと安心です。。


# 色々試してみた！（もがいてみた）
ほぼ上記の答えが真でこれ以上何もできないような気がしたのですが、勉強も兼ねてサイズダウンする方法を調査してまとめてみました。

## General周り
1. 対応デバイスの確認
 今回はiPhoneのみの対応なので、以下のように設定しました！
 * Deployment Info →　**iPhone**<br>
→元々設定していたので上記のサイズからは変わらず。。

1. Embededded Binaries
 * ここに不要なバイナリが入るとipaのサイズに影響が出るらしいので確認！<br>
 →何も入ってませんでした＼(^o^)／よって変わらず。。

## Build Setting 周り
### Optimization Level
色んな部分で最適化できるみたいなので、こちらも導入してみました！

* Apple LLVM 9.0 - Code Generation
コードを生成する時の、最適化レベルを設定できます。
 * Optimization Level → **Fastest, Smallest [-Os]**<br>
→目に見えた効果は得られず。。

* Swift Compiler - Code Generation
Swiftのコンパイル方法を制御する部分みたいです。Sizeを減らすことを優先にした最適化にします。
 * Optimization Level → **Optimize for Size [-Osize]**<br>
→ 約2.6MBダイエット！　この時点では有効にしてたのですが、後々ちょっと厄介なことが起きました。(後述)

* Asset Catalog Compiler - Options
アセットのコンパイルを制御できるみたいです。 
 * Optimization → **space**<br>
→　0.2MBダイエット成功！ 画像がかなり入っていたので効果が得られたのかもしれません。

### Deployment Postprocessing
デバッグ情報をビルド内に含めるか否かの設定です。(Noにすると情報を含んでくれるそうです。)

* Deployment Postprocessing→ **Yes**<br>
→元々設定されていたので変化なし。

### Symbols Hidden by Default
出力するシンボル情報を制限する機能です。（Yesにするとメソッドのシンボル名を隠すことができます。）

* Symbols Hidden by Default→ **Yes**<br>
→目に見えた効果は得られず。。

### Valid Architectures
ここではどのアーキテクチャを対象にビルドするかが書いてあります。（[こちらの記事](https://qiita.com/takkyun/items/814aa45beee422a5f0c6)が参考になりました！）
本アプリの対応OSは**9**からのため、デフォルトは**armv7, armv7s, armv64**でした。
この設定を試しに以下のようにしてみました！

* armv7, armv7s, armv64　→　**armv64(iPhone5s以降の対応となる)**<br>
→ 1.4MBダイエット！

試しに設定を変えてアーカイブはしましたが、対応OSを変更する訳にはいかないため、この設定は却下しました。
（対応OSによっては有効策だと思います！）


### Enable Bitcode
これはBitcodeを有効にするか否かの設定です。
#### Bitcodeとは？
公式ではこのように説明されています。→[App Thinning（iOS、tvOS、watchOS）](https://developer.apple.com/jp/documentation/IDEs/Conceptual/AppDistributionGuide/AppThinning/AppThinning.html)
書いてある通りですが、コンパイル済みプログラムの中間表現のことであり、この設定を有効にするとストア側で再コンパイルをするなどよしなに最適化をしてくれるというものです！
普通はONにするみたいですが、試しに変えてみました。

* Enable Bitcode　→　**No**<br>
→　38.5MBダイエット！

かなり削減できました！それはそうでしょ…という感じですが、Apple側の最適化の恩恵が無くなるのは痛いのであまり有効策ではないように感じます。
ただ、プロジェクトに積んでいるライブラリによってはBitcodeに対応していない場合もあるので、その時は無効にしても良いのかもしれません。

## Build Phases 周り
ここに不要なファイルが入っていると、容量を食い潰してしまうので、確認しました！

* Link Binary With Libraries<br>
→　不要なライブラリは無いことを確認。
* Copy Bundle Resources
→　不要なリソースがあったため削除。（ここに何か入っていると、そもそもipaファイルが作成できませんでした。→[参考](https://github.com/CocoaPods/CocoaPods/issues/4450)）

## そもそもコード自身のダイエットが必要？
とは言うものの、元々が簡素なだけあって、あまり削る部分もなかったので、以下のことのみ対応しました。
### 不要なライブラリが無いか確認
意味もなくimportしているライブラリは無いか、確認しました！

* 不要なライブラリを削除<br>
→目に見えた効果は得られず。。（コードの整理はできたので良しとします！）

### log出力周りをコメントアウト
* logをprint文で出力していたので、1つ1つコメントアウト。。<br>
→0.1MBダイエットできました！が、微々たるものと、あまり有効策では無いので却下することに。。

## やったこと・確認したことまとめ
一覧にしてみるとこんな感じです。
（結果のところはあくまで私のコードの結果なので、参考程度にしてください。。）

|種類|どの設定|やったこと|結果|適用したか？|
|:--|:--|:--|:--|:--|
|General|Embedded Binaries|不要なバイナリが無いか確認|なかった|○|
|General|Deployment Info|iPhone|元々設定されていた。。|○|
|Build Setting|AppleLLVM9.0|Fastest, Smallest|元から設定されていた。。|○|
|Build Setting|Asset Catalog Compiler Optimization|Space|0.2MBダイエット！|○|
|Build Setting|Swift Compiler - CodeGeneration Optimize Level|Optimize for Size|2.6MBダイエット！|×(後述)|
|Build Setting|Deployment Postprocessing|Yes|元から設定されていた。。|◯|
|Build Setting|Symbols Hidden by Default|Yes|元から設定されていた。。|◯|
|Build Setting|Build Options Enable BitCode|No|38.5MBダイエット！|△|
|Build Setting|Architectures Valid Architectures|arm64 のみにする|3MBダイエット|×|
|Build Phases|Link Binary With Libraries|不要なライブラリが無いか確認|特になし|○|
|Build Phases|Copy Bundle Resources|不要なリソースが無いか確認|一部削除|○|
|コード修正|log関連|print文をコメントアウト|0.1MBダイエット!|×|
|コード修正|ライブラリ|不要なライブラリを削除|あまり変化なし|○|


# アップロードした→iTunesConnectでエラー。。
![スクリーンショット 2018-05-07 17.52.38.png](https://qiita-image-store.s3.amazonaws.com/0/251327/4865fa6a-ede9-90de-5ab9-b92db520271a.png)
こんな感じですorz

で、エラーコードは以下のように書いてありました。

```
Invalid Bundle - The app cannot be processed becauseoptions not allowed to be embedded in bitcode are detected in the submission. 
It is likely that you are not building the app with the toolchain provided in Xcode. 
Rebuild your entire app with the latest GM Xcode and submit the app again. 
```
…検討がつかないため、ググってみたところ、以下のような記事が！
[Invalid bundle "Rebuild your entire app with the latest GM Xcode and submit the app again" with Xcode 9.3](https://forums.developer.apple.com/thread/99480)

この記事によると、**Optimization Level**を**Optimize for Size**にするとiTunesConnectで**リジェクト**されるとのことでした。
ということで早速以下の設定に変更して再アップロードをしました。

|種類|どの設定|やったこと|結果|適用したか？|
|:--|:--|:--|:--|:--|
|Build Setting|Swift Compiler - CodeGeneration Optimize Level|No Optimization|2.6MBリバウンド|○|

結果は…
![スクリーンショット 2018-05-07 18.20.07.png](https://qiita-image-store.s3.amazonaws.com/0/251327/76ea6025-1b3a-0b20-0bd9-67996cf727b5.png)
通った！:tada:

そもそもこの機能はSwift4.1で追加された機能らしく([参考](https://swift.org/blog/osize/))、まだ挙動が不安定だったのかもしれませんね。。うーん。。

# ファイルサイズの確認！
本題に戻りまして、ファイルサイズを確認しました！
確認方法はアクティビティ→すべてのビルド→圧縮ファイルのサイズ→App Storeファイルのサイズ です。

<img width="783" alt="スクリーンショット 2018-05-07 18.19.01.png" src="https://qiita-image-store.s3.amazonaws.com/0/251327/5427da3f-823f-df5b-0ccc-e80de94a9dad.png">

確かに圧縮されてる…！これで一安心です😌
しかし約１００MBからここまで下がるものなんですねー。もう少しライブラリが小さくなるか、ipa内に持つ必要が無くなれば良いのですが。。

# 最後に
初めてiOSアプリを作るにあたって、Swiftが主流だからSwiftで書いてきましたが、根底にはObjective-Cの存在はずっとあり、多少なりともその知識はあった方が良いのかな〜と思いました。
すごい悩んでしまいましたが、色々勉強できる良い機会でした！

まだ素人に毛の生えた程度の人が書いているため、間違いが記載されているかもしれません。
もし見つけた方は是非とも指摘していただけますとありがたいですm(_ _)m

# お世話になったページ
色々調査するにあたって、参考にしたページです。とても勉強になりました！ありがとうございますm(_ _)m

* [Reducing the size of my App](https://developer.apple.com/library/content/qa/qa1795/_index.html)
* [Export an iOS, tvOS, or watchOS app](https://help.apple.com/xcode/mac/current/#/dev23ea8b877)
* [[iOS] 新規インストール時のアプリサイズを計測し、最適化を行なう方法について](https://dev.classmethod.jp/smartphone/reducing-the-size-of-ios-app/)
* [Swift と Objective-C どっち選ぶ？](http://blog.sorausagi.org/2017/10/swift-objective-c.html)
* [サイズにコミット！意外と知らないiOSアプリのダイエット方法](http://www.bravesoft.co.jp/blog/archives/1284)
* [otoolでバイナリの内容をいろいろと調べる方法](http://d.hatena.ne.jp/shu223/20110518/1305738227)
* [iOSデバイス一覧表](https://qiita.com/takkyun/items/814aa45beee422a5f0c6)
* [Invalid bundle "Rebuild your entire app with the latest GM Xcode and submit the app again" with Xcode 9.3](https://forums.developer.apple.com/thread/99480)
* [Code Size Optimization Mode in Swift 4.1](https://swift.org/blog/osize/)