CharlesでiOS Simulatorの通信をキャプチャする方法

パケットキャプチャツール「**Charles**」を用いて、iOS端末（特にiOS Simulator）の通信をキャプチャする方法についてまとめます。
また、Charlesは通信のキャプチャだけでなく、レスポンスの差し替えなどもツール上から行えるのでとても便利です。

# こんなときに役に立ちます！
- Xcodeでのデバッグでは追いにくい、**実際の通信処理の中身**を確認したい
- iOSアプリの結合試験時など、**無駄にリクエストをしていないか**確認したい
- 実機でパケットキャプチャする時の**プロキシの設定が毎回めんどくさい**（←自分は地味にこれです）

# 必要なものはMacだけ
- Mac
  - Xcode (iOS Simulator) ※Xcodeの導入方法は割愛
  - Charles (パケットキャプチャツール)
      - 無料でも使えます

# やり方
一度設定してしまえば、以降はCharlesを起動するだけで通信のキャプチャが可能です:tada:

### Charlesの設定
1. [こちら](https://www.charlesproxy.com/download/)から最新版をインストールします
    - Homebrewでインストールすることもできます  
    
    ```
    $ brew tap homebrew/cask
    $ brew cask install charles
    ```

2. インストールが完了したらCharlesを起動します
3. ダイアログが出るので、Grant Privilegesを選択します
    <img width="780" alt="スクリーンショット 2018-02-14 12.56.46.png" src="https://qiita-image-store.s3.amazonaws.com/0/128422/7dda3990-fd55-6195-c794-3ebba1164c47.png">
4. メニューバーのProxy > Proxy Settingsを選択し、下記のキャプチャの通り、Enable transparent HTTP Proxyingをチェックします
    <img width="592" src="https://qiita-image-store.s3.amazonaws.com/0/128422/ce3909a6-0c0d-75e6-7c33-19eb8be90167.png">
5. メニューバーのProxy > SSL Proxy Settingsを選択し、下記のキャプチャの通り、HTTP Proxyを設定します
    <img width="592" src="https://qiita-image-store.s3.amazonaws.com/0/128422/ab6f204c-1d1d-300d-6024-0b40f3c73d1e.png">

### Charlesの証明書の設定
Charlesでパケットキャプチャするには、証明書を対象のmacOS/iOS端末に登録する必要があります。
この登録処理自体をしなくてもパケットキャプチャ自体はできるのですが、SSL(https)通信まではキャプチャできないので、SSL通信をキャプチャしたい場合は、この設定が必要となります。
やっておいて損はないと思います。

1. メニューバーのHelp > SSL Proxying > Install Charles Root Certificateを選択します
2. キーチェーンアクセスに追加されたか確認します（charlesで検索するとよいです）
    <img width="877" src="https://qiita-image-store.s3.amazonaws.com/0/128422/d7b5b66a-8efb-1dd4-eb8e-85f84c8a2018.png">
3. 赤いバツマークになっているので、右クリックして情報をみるを選択し、信頼セクションを展開して、この証明書を利用するときの「常に信頼」に変更します
    <img width="512" src="https://qiita-image-store.s3.amazonaws.com/0/128422/0a6025d0-f1e7-5b39-502e-2feb04ddfffc.png">
4. 赤いバツマークがなくなればOKです
    <img width="877" src="https://qiita-image-store.s3.amazonaws.com/0/128422/4ef4a3d8-f8b0-1800-1f5f-99830cc6fdf3.png">

### iOS Simulatorの証明書設定
1. メニューバーのHelp > SSL Proxying > Install Charles Root Certificate in iOS Simulatorを選択します
2. ダイアログが出るのでOKを選択します
    <img width="780" alt="スクリーンショット 2018-02-17 17.36.00.png" src="https://qiita-image-store.s3.amazonaws.com/0/128422/cef26df6-974e-6bbf-746f-05ec090a7336.png">


### iOS Simulator上の設定(iOS10.3以降)
:warning: iOS10.3以降のSimulatorにて、https(SSL通信)の中身をキャプチャするには、下記設定が必須となりますのでご注意ください
1. Charlesを起動します
2. 通信をキャプチャしたいiOS Simulatorを起動します
3. 設定(Settings).Appを開き、一般(General) > 情報(About) > 証明書信頼設定(Certifiacte Trust Settings) > Charles Proxy CA のスイッチをOnにします
    <img width="375" src="https://qiita-image-store.s3.amazonaws.com/0/128422/b6205353-78b4-bfc8-cda9-c84bdfcf4c6a.png">


# Let's Capture!!!
1. 試しに先ほど設定したSimulatorでSafariでAppleのサイトを開いてみます
2. 正常にSSL通信がキャプチャできているのがわかりますね:+1:
    <img width="1280" alt="貼り付けた画像_2018_02_17_17_47.png" src="https://qiita-image-store.s3.amazonaws.com/0/128422/1a09e27d-8110-c041-d709-d102796d67c4.png">


# 実機ではどうやるの？
iPhone/iPadなどの実機の場合も、同様にCharlesメニューバーのHelpからMobile Device用のRootCertificateを実機にインストールすれば可能です。
が、通信をPCでキャプチャするために端末のネットワーク設定に対してプロキシを毎回設定しなくてはならないので、ちょっぴりめんどくさいです。
また、キャプチャ完了した後にプロキシの設定を有効にしたまま閉じてしまって、通信を使うときにエラーになってなんでだろう？とよくなってしまいがちなので、Simulatorの方がよく使います。

# まとめ
Charlesを使ってiOS Simulatorにて通信キャプチャをするための手順を書きました。
無駄に通信をしているアプリを生み出してしまうのは、ユーザにとってもサーバにとっても負荷が高いので、通信キャプチャをしながらエコなアプリを提供しましょう。
最後までお読みいただき、ありがとうございました。