macOS で ネットからURLでダウンロードするコードが動かなくなり焦って調べてみた

### macOS のアプリのコードでネットからのコンテンツがダウンロードされない！？

macOS の cocoaアプリの新規プロジェクトを作り、こんなコードを書いたら動かない事に気がつきました。

```.swift
do {
	let url = URL(string: "https://www.apple.com")!
	var encoding = String.Encoding.utf8
	let text = try String(contentsOf: url, usedEncoding: &encoding)
	print("contents: \(text)")
}
catch {
	print("error: \(error)")
}
```

エラーのログはだいたいこんな感じです。

```error.log
dnssd_clientstub ConnectToServer: connect()-> No of tries: 1
dnssd_clientstub ConnectToServer: connect()-> No of tries: 2
dnssd_clientstub ConnectToServer: connect()-> No of tries: 3
dnssd_clientstub ConnectToServer: connect() failed path:/var/run/mDNSResponder Socket:11 Err:-1 Errno:1 Operation not permitted
[] nw_resolver_create_dns_service_locked DNSServiceCreateDelegateConnection failed: ServiceNotRunning(-65563)
TIC TCP Conn Failed [1:0x604000162040]: 10:-72000 Err(-65563)
Task <7E9A6646-3924-4A82-868D-DA280CA5ECFC>.<0> HTTP load failed (error code: -1003 [10:-72000])
NSURLConnection finished with error - code -1003
Error Domain=NSCocoaErrorDomain Code=260 "The file couldn’t be opened because it doesn’t exist." UserInfo={NSURL=https://www.apple.com, NSUnderlyingError=0x6000000500e0 {Error Domain=NSURLErrorDomain Code=-1003 "A server with the specified hostname could not be found." UserInfo={NSUnderlyingError=0x608000440ed0 {Error Domain=kCFErrorDomainCFNetwork Code=-1003 "A server with the specified hostname could not be found." UserInfo={NSErrorFailingURLStringKey=https://www.apple.com/, NSErrorFailingURLKey=https://www.apple.com/, _kCFStreamErrorCodeKey=-72000, _kCFStreamErrorDomainKey=10, NSLocalizedDescription=A server with the specified hostname could not be found.}}, NSErrorFailingURLStringKey=https://www.apple.com, NSErrorFailingURLKey=https://www.apple.com, _kCFStreamErrorDomainKey=10, _kCFStreamErrorCodeKey=-72000, NSLocalizedDescription=A server with the specified hostname could not be found.}}}
```

ちょっと前まで書いていた似たようなコードではちゃんと動いていました。ここで、ひらめきます。「あ！これはあれだ！`App Transportation Security`の問題かな？」とそこで、`info.plist` を開いてこんな感じで `App Transportation Security` を追加して `Allow Arbitrary Loads` を `YES` にします。

<img width="571" alt="Screen Shot 2017-10-02 at 23.35.28.png" src="https://qiita-image-store.s3.amazonaws.com/0/65634/4104ecbf-e07b-5ac0-1cb0-4a939e7e5c14.png">

実行するとやはり、同じエラーで、コンテンツをダウンロードしてくれません。そこで、エラーの一部からググってみますが、問題の解決にたどり着けそうにありません。

で、プロジェクトをよく見るとこれまでに見慣れないものが入っている事に気がつきます。「.entitlements」です。「はは〜ん！Xcode 9で新規に作ったcocoaのアプリのプロジェクトにはデフォルトで入るのだな！」そこで、Xcode8 と Xcode9 でそれぞれ新しくcocoaのアプリのプロジェクトを作ってみます。左が Xcode8 で右が Xcode9 です。

<div>
<img width="261" alt="screen_shot_1.png" src="https://qiita-image-store.s3.amazonaws.com/0/65634/1f52cc4a-510b-7b26-8678-1510582d91b7.png">

<img width="275" alt="screen_shot_1.png" src="https://qiita-image-store.s3.amazonaws.com/0/65634/786bbaa0-5eac-5e0a-1457-fe92435b4c64.png">
</div>

やっぱり、Xcode 9で作ったプロジェクトには「.entitlements」がふえています。

<img width="559" alt="Screen Shot 2017-10-03 at 0.02.26.png" src="https://qiita-image-store.s3.amazonaws.com/0/65634/7dbd7ef8-0784-9023-2a74-8ff3c9c096c4.png">

そこで `com.apple.security.app-sandbox` や `com.apple.security.files.user-selected.read-only` で検索してみます。

#### Enabling App Sandbox
https://developer.apple.com/library/content/documentation/Miscellaneous/Reference/EntitlementKeyReference/Chapters/EnablingAppSandbox.html

なるほど、Cocoa アプリ が Sandbox化 されるなら、各々の機能別にこれで指定しないとダメだよね。という事で、一覧を眺めて `com.apple.security.network.client` を Xcode9 で作成されたプロジェクトに入れてみました。

<img width="586" alt="Screen Shot 2017-10-02 at 23.39.08.png" src="https://qiita-image-store.s3.amazonaws.com/0/65634/a17fdf56-8312-c10d-beb3-48d03df99819.png">

これで、再度冒頭のスニペットを組み込んで実行させると、見事ネットからURLでコンテンツをロードしてくれました。

なお、エラーメッセージで検索しても、解決できるページにたどりつかなかった為、今後、同様な問題を抱えた人がエラーメッセージを頼りに検索したした時に、ここにだどりつけるように、エラーメッセージなどもほぼそのまま掲載する事とします。

### 最後に

あと、既に気がついている人はいるかもしれませんが、冒頭のスニペットが動かないので `App Transportation Security` で `Allow Arbitrary Loads` を `YES` すればいいと思いましたが、そもそも `https://` でアクセスしてるのでこの思考の流れは残念でした。

また、macOS の Sandbox化が進むとユーザーには良いかもしれませんが、開発者には面倒な時代になっていくなぁという思いが交差しています。

### 環境に関する表記

```
Xcode 8: Xcode 8.3.3 (8E3004b)
Xcode 9: Xcode 9 (9A235)
```