はじめに
Flutterでスマホアプリを開発中、天気APIにアクセスしようとしたところ、以下のエラーが発生しました。
flutter: ❌ Error fetching weather data: ClientException with SocketException: Connection failed (OS Error: Operation not permitted, errno = 1), address =
api.openweathermap.org, port = 443
HTTPリクエストは正常に書けているのに、なぜか接続できない...。なんでや...?
原因
デフォルトで App Sandbox というセキュリティ機能が有効になっており、ネットワークアクセスが制限されているみたい。
macos/Runner/DebugProfile.entitlements を確認すると、以下のようになっていました:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.app-sandbox</key>
<true/>
<key>com.apple.security.cs.allow-jit</key>
<true/>
<key>com.apple.security.network.server</key>
<true/>
</dict>
</plist>
問題点:
- com.apple.security.network.server はあるが、これは「サーバーとして待ち受ける権限」
- 外部へ接続する権限(com.apple.security.network.client)が不足している
解決方法
- DebugProfile.entitlements を修正
macos/Runner/DebugProfile.entitlements に以下を追加:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.app-sandbox</key>
<true/>
<key>com.apple.security.cs.allow-jit</key>
<true/>
<key>com.apple.security.network.server</key>
<true/>
<!-- ↓ この行を追加 -->
<key>com.apple.security.network.client</key>
<true/>
</dict>
</plist>
- Release.entitlements も修正
macos/Runner/Release.entitlements にも同様に追加:
com.apple.security.app-sandbox com.apple.security.network.client- クリーンビルドして再実行
flutter clean
flutter run
修正後、正常にHTTPリクエストが成功するようになります:
App Sandboxの権限について
macOSのApp Sandboxでは、以下のような権限を個別に指定する必要があります:
| キー | 説明 | 用途 |
|---|---|---|
| com.apple.security.app-sandbox | App Sandboxを有効化 | 必須 |
| com.apple.security.network.client | 外部への接続 | HTTP/API通信 |
| com.apple.security.network.server | 待ち受けポートを開く | Webサーバー機能 |
| com.apple.security.files.user-selected.read-write | ユーザーが選択したファイルへのアクセス | ファイル操作 |
| com.apple.security.device.camera | カメラへのアクセス | カメラ機能 |
ポイント:
- network.server ≠ network.client
- 外部APIにアクセスする場合は network.client が必要
今回レスポンスを受け取れなかった原因
❌ network.server だけ設定している
network.server はサーバー機能(ポートを開いて待ち受ける)の権限で、外部への接続には使えないようです。
✅ network.client を追加する
com.apple.security.network.client
参考