概要
iOS 9以上ではApp Transport Securityの導入により、HTTPリクエストを実行するとエラーが発生する。その対応。
Info.plistの設定変更
<プロジェクト名>.iOS
以下にあるInfo.plist
を開き、以下の設定を追加する。
NSAppTransportSecurity
については以下を参照。
https://developer.apple.com/documentation/bundleresources/information_property_list/nsapptransportsecurity
*iOS 10以上ではこの設定が無視される、と書いてあるがApp Transport Securityの導入が延期(https://developer.apple.com/news/?id=12212016b)された結果、現状ではiOS 13でも問題なく適用されている。
サンプルコード
"http://www.google.com"に対するGETリクエストを実行する。
static readonly HttpClient client = new HttpClient(); private static async Task HttpRequestAsync() { HttpResponseMessage response = await client.GetAsync("http://www.google.com"); response.EnsureSuccessStatusCode(); byte[] responseBody = await response.Content.ReadAsByteArrayAsync(); Console.WriteLine("responseBody=" + Encoding.UTF8.GetString(responseBody)); } async void OnButtonClicked(System.Object sender, System.EventArgs eventArgs) { try { await HttpRequestAsync(); } catch (Exception e) { Console.WriteLine($"{e}"); } }
設定変更前の実行結果
App Transport SecurityによってHTTPリクエストがブロックされる。
2020-04-29 22:14:23.652 XamarinHttp.iOS[2498:840291] 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. Thread started: #4 2020-04-29 22:14:23.678 XamarinHttp.iOS[2498:840277] System.Net.Http.HttpRequestException: The resource could not be loaded because the App Transport Security policy requires the use of a secure connection. ---> Foundation.NSErrorException: Error Domain=NSURLErrorDomain Code=-1022 "The resource could not be loaded because the App Transport Security policy requires the use of a secure connection." UserInfo={NSLocalizedDescription=The resource could not be loaded because the App Transport Security policy requires the use of a secure connection., NSErrorFailingURLStringKey=http://www.google.com/, NSErrorFailingURLKey=http://www.google.com/, _NSURLErrorRelatedURLSessionTaskErrorKey=( "LocalDataTask <63869A38-EDA0-4689-A5F0-2FF17C08DDB8>.<1>" ), _NSURLErrorFailingURLSessionTaskErrorKey=LocalDataTask <63869A38-EDA0-4689-A5F0-2FF17C08DDB8>.<1>, NSUnderlyingError=0x281297480 {Error Domain=kCFErrorDomainCFNetwork Code=-1022 "(null)"}} --- End of inner exception stack trace --- at System.Net.Http.NSUrlSessionHandler.SendAsync (System.Net.Http.HttpRequestMessage request, System.Threading.CancellationToken cancellationToken) [0x001d4] in /Library/Frameworks/Xamarin.iOS.framework/Versions/13.16.0.13/src/Xamarin.iOS/Foundation/NSUrlSessionHandler.cs:462 at System.Net.Http.HttpClient.FinishSendAsyncBuffered (System.Threading.Tasks.Task`1[TResult] sendTask, System.Net.Http.HttpRequestMessage request, System.Threading.CancellationTokenSource cts, System.Boolean disposeCts) [0x0017e] in /Library/Frameworks/Xamarin.iOS.framework/Versions/Current/src/Xamarin.iOS/external/corefx/src/System.Net.Http/src/System/Net/Http/HttpClient.cs:506 at XamarinHttp.MainPage.HttpRequestAsync () [0x0002f] in /Users/shindo/Projects/XamarinHttp/XamarinHttp/MainPage.xaml.cs:31 at XamarinHttp.MainPage.OnButtonClicked (System.Object sender, System.EventArgs eventArgs) [0x0002e] in /Users/shindo/Projects/XamarinHttp/XamarinHttp/MainPage.xaml.cs:54
設定変更後の実行結果
問題なくHTTPリクエストが実行できる。
2020-04-29 21:54:06.596 XamarinHttp.iOS[2493:836960] responseBody=<!doctype html> <html> <head> <title>Example Domain</title> <meta charset="utf-8" /> <meta http-equiv="Content-type" content="text/html; charset=utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1" /> <style type="text/css"> body { background-color: #f0f0f2; margin: 0; padding: 0; font-family: -apple-system, system-ui, BlinkMacSystemFont, "Segoe UI", "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif; } div { width: 600px; margin: 5em auto; padding: 2em; background-color: #fdfdff; border-radius: 0.5em; box-shadow: 2px 3px 7px 2px rgba(0,0,0,0.02); } a:link, a:visited { color: #38488f; text-decoration: none; } @media (max-width: 700px) { div { margin: 0 auto; width: auto; } } </style> </head> <body> <div> <h1>Example Domain</h1> <p>This domain is for use in illustrative examples in documents. You may use this domain in literature without prior coordination or asking for permission.</p> <p><a href="https://www.iana.org/domains/example">More information...</a></p> </div> </body> </html>