iOS9でHTTP通信ができない時の解決法

iOS9.0からはHTTPS通信が推奨されているようで、App Transport Security(以下ATS)が有効である場合は何も設定しないとHTTP通信ができなくなってしまいます。
今回はその対処法についてまとめます。

# エラー内容

何も対応しない状態でHTTP通信を行うと以下のログが出力されます。

```
App Transport Security has blocked a cleartext HTTP (http://) resource load 
since it is insecure. 
Temporary exceptions can be configured via your app's Info.plist file.
```

# 解決方法の説明に入る前に

.plistでPropertyList上からネストを作る方法です。
例えばApp Transport Security Settingsの下の階層にkey-valueの行を追加してしたい場合に以下の状態で「＋」をクリックしてもネストは作られません。
![スクリーンショット 2015-12-29 20.58.45.png](https://qiita-image-store.s3.amazonaws.com/0/100736/f9640b11-b8e6-4149-4de6-a9730a52ba79.png)
↓
![スクリーンショット 2015-12-29 22.20.35.png](https://qiita-image-store.s3.amazonaws.com/0/100736/c5a2c63b-6dc2-9a03-5dfe-ba9c3417b751.png)

ネストを作るには、左端の三角を▶︎ではなく▼の状態にする必要があります。
▼の状態で「＋」をクリックすれば下の階層にkey-valueの行が追加されます。
![スクリーンショット 2015-12-29 22.24.12.png](https://qiita-image-store.s3.amazonaws.com/0/100736/38e4fc0c-ce7a-331b-b3a5-440b993b2712.png)
↓
![スクリーンショット 2015-12-29 22.24.26.png](https://qiita-image-store.s3.amazonaws.com/0/100736/f594d104-a2be-0926-8696-f2b75b2029b6.png)


# 解決方法1：ATSを無効にする(非推奨)

Info.plistを編集します。

## PropertyListで編集する場合

### keyにApp Transport Security Settingsを追加する

適当な行の「＋」ボタンをクリックします。
下の画像ではMain storyboard file base nameの「＋」をクリックし、その下に新しい行が追加された状態です。

![スクリーンショット 2015-12-29 19.49.43.png](https://qiita-image-store.s3.amazonaws.com/0/100736/fd58248b-b844-b5a8-e8ac-2df48a69763b.png)

画像にある通り、keyの候補は色々と出てくるのですが、その中に今回必要なkeyがないので自分で「NSAppTransportSecurity」と入力します。
Enter押すと「App Transport Security Settings」に名前が変わります。

### ATSを無効にする

今度はApp Transport Security Settingsの「＋」をクリックしてください。
こんな表示になるはずです。
![スクリーンショット 2015-12-29 19.59.57.png](https://qiita-image-store.s3.amazonaws.com/0/100736/368af0f3-ea02-e19c-0b53-593765317357.png)
ここでAllow Arbitrary Loadsを選択し、valueはYESにします。

### 完成形

![スクリーンショット 2015-12-29 19.58.54.png](https://qiita-image-store.s3.amazonaws.com/0/100736/02903f06-d24d-96bd-2326-046e8c5723de.png)

## コードで編集する場合

```
<key>NSAppTransportSecurity</key>
<dict>
    <key>NSAllowsArbitraryLoads</key>
    <true/>
</dict>
```

# 解決方法2：ATSを使用しつつ、一部のドメインを許可する

## PropertyListで編集する場合

### keyにApp Transport Security Settingsを追加する

解決方法1と同様です。

### 例外ドメインの設定

先程はkeyにAllow Arbitrary Loadsを選択しましたが、今度はException Domainsを選択します。
Exception Domainsの行の「＋」をクリックして行を追加します。
New itemとなっている部分を許可したいドメインに書き換えます。
TypeがStringになっていると思うので、Dictionaryに変更します。
今現在こんなかんじだと思います。

![スクリーンショット 2015-12-29 20.52.09.png](https://qiita-image-store.s3.amazonaws.com/0/100736/d1e58cd7-dd16-2c73-ed7e-ff03559a6148.png)


この状態だとまだドメインを指定しただけでそれをどうするのかを記述していないので、その指定をするkey-valueを付け足します。
ドメインを記述した行の「＋」をクリックし、行を追加します。
New ItemをNSTemporaryExceptionAllowsInsecureHTTPLoadsに変えます。
このままだとStringなのでBooleanに変えてvalueをYESにします。

### 完成形

![スクリーンショット 2015-12-29 20.52.09.png](https://qiita-image-store.s3.amazonaws.com/0/100736/f88807c9-6548-d578-6996-5abf53932687.png)

## コードで編集する場合

```
<key>NSAppTransportSecurity</key>
<dict>
    <key>NSExceptionDomains</key>
    <dict>
        <key>example.com</key>
        <dict>
            <key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key>
            <true/>
        </dict>
    </dict>
</dict>
```

# その他の解決方法

セキュリティレベルを下げる方法、基本的にATSを無効にするものの、一部のドメインをATSの対象にするという方法もありますが、よく使うのは上記2つではないのかなぁと思っています。

もっと詳しく知りたい場合はこちらの情報源が良いのではないかと思います。
http://www.neglectedpotential.com/2015/06/working-with-apples-application-transport-security/
http://shirakiya.hatenablog.com/entry/2015/10/03/234816
http://dev.classmethod.jp/smartphone/iphone/ios-9-intro-ats/