With the release of iOS 9 last week, Apple has introduced new under-the-hood features meant to protect the end-user and their privacy. While this is a welcome addition, said features may break your app if not addressed properly.
App Transport Security
According to Apple, App Transport Security is a feature that improves the security of connections between an app and web services. The feature consists of default connection requirements that conform to best practices for secure connections.
These are the App Transport Security requirements:
- The server must support at least Transport Layer Security (TLS) protocol version 1.2.
- Connection ciphers are limited to those that provide forward secrecy (see the list of ciphers below.)
- Certificates must be signed using a SHA256 or greater signature hash algorithm, with either a 2048-bit or greater RSA key or a 256-bit or greater Elliptic-Curve (ECC) key.
Invalid certificates result in a hard failure and no connection.
The default behaviour causes all connections using NSURLConnection, CFURL, or NSURLSession to fail if they don’t follow these requirements.
Luckily, this layer of security can be disabled pretty easily by adding an exception into your Info.plist file. Just add a NSAppTransportSecurity dictionary to the .plist and inside of that a NSExceptionDomains dictionary with the desired exceptions. You can also disable the transport security altogether by adding a NSAllowsArbitraryLoads boolean to the first dictionary. For more options just check the relative Apple technote.
Privacy and URL Scheme Changes
URL schemes are used by many apps for a variety of purposes. A common use is to deep link to a particular piece of content within an app – seen as an “Open in app” link from a web page.
Before trying to open a URL handled by another app (using NSApplication’s openURL: method) it’s good practice to check if that app is actually installed on the device. NSApplication’s canOpenURL: method used to return a YES or NO answer after checking if there were any apps installed on the device that know how to handle the given URL.
With iOS 9, canOpenURL: can’t be used on arbitrary URLs anymore. Apple noticed that some apps were using this method to collect information about what apps were or were not installed on the user’s device for marketing and other purposes the method was not intended for.
From now on canOpenURL: will return NO even if there is an app able to handle the given URL, unless said URL has been whitelisted in the app Info.plist before submission to the App Store. These limits will be retroactively enforced on apps built and submitted to the store prior to iOS 9 by the system, which will build it’s own whitelist of up to 50 URL schemes allowed for an app based on the actual calls made by the app.
To whitelist the URL schemes your app needs to function properly, just a LSApplicationQueriesSchemes array into your Info.plist and individual allowed schemes inside of that array.
This new limitations should not take long to adjust to for apps that use canOpenURL: sparingly, but it can have a very big impact on launcher-style apps that heavily rely on them. For more information about this, check out Apple Privacy and Your App video and Awkard Hare’s Quick Take on iOS 9 URL Scheme Changes.