HttpClient and SSL/TLS implementation selector for iOS/macOS
The HttpClient Implementation Selector for Xamarin.iOS, Xamarin.tvOS, and Xamarin.Mac controls which HttpClient
implementation to use. You can switch to an implementation that uses iOS, tvOS, or macOS native transports (NSUrlSession
or CFNetwork
, depending on the OS). The upside is TLS 1.2-support, smaller binaries, and faster downloads; the downside is that it requires the event loop to be running for async operations to be executed.
Projects must reference the System.Net.Http assembly.
Warning
April, 2018 – Due to increased security requirements, including PCI compliance, major cloud providers and web servers are expected to stop supporting TLS versions older than 1.2. Xamarin projects created in previous versions of Visual Studio default to use older versions of TLS.
In order to ensure your apps continue to work with these servers and services, you should update your Xamarin projects with the NSUrlSession
setting shown below, then re-build and re-deploy your apps to your users.
Selecting an HttpClient stack
To adjust the HttpClient
being used by your app:
- Double-click the Project Name in the Solution Explorer to open the Project Options.
- Switch to the Build settings for your project (for example, iOS Build for a Xamarin.iOS app).
- From the HttpClient Implementation dropdown, select the
HttpClient
type as one of the following: NSUrlSession (recommended), CFNetwork, or Managed.
Tip
For TLS 1.2 support the NSUrlSession
option is recommended.
NSUrlSession
The NSURLSession
-based handler is based on the native NSURLSession
framework available in iOS 7 and newer.
This is the recommended setting.
Pros
- It uses native APIs for better performance and smaller executable size.
- Support for the latest standards such as TLS 1.2.
Cons
- Requires iOS 7 or later.
- Some
HttpClient
features/options are not available.
CFNetwork
The CFNetwork
-based handler is based on the native CFNetwork
framework available in iOS 6 and newer.
Pros
- It uses native APIs for better performance and smaller executable size.
- Support for newer standards such as TLS 1.2.
Cons
- Requires iOS 6 or later.
- Not available on watchOS.
- Some HttpClient features/options are not available.
Managed
The Managed handler is the fully managed HttpClient handler that has been shipped with previous version of Xamarin.
Pros
- It has the most compatible feature set with Microsoft .NET and older Xamarin versions.
Cons
- It is not fully integrated with the Apple OSes and is limited to TLS 1.0. It may not be able to connect to secure web servers or cloud services in the future.
- It typically much slower at things like encryption than the native APIs.
- It requires more managed code, thus creating a larger app distributable.
Programmatically setting the HttpMessageHandler
In addition to the project-wide configuration shown above, you can also instantiate an HttpClient
and inject the desired HttpMessageHandler
through the constructor, as demonstrated in these code snippets:
// This will use the default message handler for the application; as
// set in the Project Options for the project.
HttpClient client = new HttpClient();
// This will create an HttpClient that explicitly uses the CFNetworkHandler
HttpClient client = new HttpClient(new CFNetworkHandler());
// This will create an HttpClient that explicitly uses NSUrlSessionHandler
HttpClient client = new HttpClient(new NSUrlSessionHandler());
This makes it possible to use a different HttpMessageHandler
from what is declared in the Project Options dialog.
SSL/TLS implementation
SSL (Secure Socket Layer) and its successor, TLS (Transport Layer Security), provide support for HTTP and other network connections via System.Net.Security.SslStream
. Xamarin.iOS, Xamarin.tvOS or Xamarin.Mac's System.Net.Security.SslStream
implementation will call Apple's native SSL/TLS implementation instead of using the managed implementation provided by Mono. Apple's native implementation supports TLS 1.2.
Warning
The upcoming Xamarin.Mac 4.8 release will only support macOS 10.9 or higher. Previous versions of Xamarin.Mac supported macOS 10.7 or higher, but these older macOS versions lack sufficient TLS infrastructure to support TLS 1.2. To target macOS 10.7 or macOS 10.8, use Xamarin.Mac 4.6 or earlier.
App Transport Security
Apple's App Transport Security (ATS) enforces secure connections between internet resources (such as the app's back-end server) and your app. ATS ensures that all internet communications conform to secure connection best practices, thereby preventing accidental disclosure of sensitive information either directly through your app or a library that it is consuming.
Since ATS is enabled by default in apps built for iOS 9, tvOS 9 and OS X 10.11 (El Capitan) and newer, all connections using NSUrlConnection
, CFUrl
or NSUrlSession
will be subject to ATS security requirements. If your connections do not meet these requirements, they will fail with an exception.
Based on your HttpClient Stack and SSL/TLS Implementation selections, you may need to make modifications to your app to work correctly with ATS.
To find out more about ATS, please see our App Transport Security guide.
Known issues
This section will cover known issues with TLS support in Xamarin.iOS.
Project failed to load with error "Requested value AppleTLS wasn't found"
Xamarin.iOS 9.8 introduced some new settings contained the .csproj file for a Xamarin.iOS application. These changes may cause problems when the project is opened with older versions of Xamarin.iOS. The following screenshot is a example of the error message that may be displayed in this scenario:
This error is caused by the introduction of the MtouchTlsProvider
setting to the project file in Xamarin.iOS 9.8. If it is not possible to update to Xamarin.iOS 9.8 (or higher), the work around is to manually edit the .csproj file application, remove the MtouchTlsprovider
element, and then save the changed project file.
The following snippet is an example of what the MtouchTlsProvider
setting may look like inside a .csproj file:
<MtouchTlsProvider>Default</MtouchTlsProvider>